Article 5110 of comp.lang.perl: Xref: feenix.metronet.com comp.lang.perl:5110 Newsgroups: comp.lang.perl Path: feenix.metronet.com!news.utdallas.edu!wupost!howland.reston.ans.net!europa.eng.gtefsd.com!uunet!tandem!max!bob From: bob@max.cpd.tandem.com (Bob Mackay) Subject: Re: Global behavior of @_ (??) Message-ID: Sender: news@tandem.com Nntp-Posting-Host: max.cpd.tandem.com Reply-To: bob@max.cpd.tandem.com Organization: Tandem Computers Inc. References: <1993Aug18.151703.1824@newt.welch.jhu.edu> Date: Wed, 18 Aug 1993 22:14:09 GMT Lines: 121 In article 1824@newt.welch.jhu.edu, kramerl@library.welch.jhu.edu (Laurie Kramer) writes: >I'm running Perl 4.036. Check this out: > >&foo(1); > >sub foo { > local ($x) = @_; > &foo2; >} > >sub foo2 { > local ($y) = @_; > print "$y\n"; # prints 1 !! >} > >Is this a bug? P. 99 of the Camel book says "The array @_ is a local array..." > >(I can get around it by setting $#_ to -1 in foo.) > >Laurie Kramer This discussion came up only a month ago. Page 101 says "If [procedure parameters] are omitted then no @_ array is set up for the subroutine; the @_ array at the time of the call is visible to the subroutine instead. IMHO this is a dreadfully dangerous feature, since in calling a subroutine that turns out to have optional parameters you need to know this and use an empty parameter list. The response a month ago was that you should ALWAYS use the &foo() form of the procedure call, which is always safe. I went to the extent of writing up a quick program to search for problems, which I attach below. I hope that this is useful. --- __ / \ | \__/__ | Bob Mackay ______ \ | Tandem Computers Inc. / / \ \ | (408) 285 4218 \ \__/ / | mackay_bob@tandem.com \_______/ | #!/usr/local/bin/perl ################################################################################ # # ATUS - AT UnderScore checker - Bob Mackay - MACKAY_BOB@TANDEM.COM # # This program finds parameterless calls to subroutines that are expecting # arguments. Such calls are equivalent to calling the subroutine as # &proc_name (@_); which is not generally what is intended. # # Known bugs: # # Arrays with names beginning with '_' are mistaken for references to '@_'. If # the subroutine does not otherwise refer to @_ it may still be flagged. # # Procs refered to in 'defined' checks (... if defined &proc_name;) look # like parameterless calls and so may be flagged. # ################################################################################ while (<>) { # strip comments s/#.*//; # look for a subroutine if (/^\s*sub\s+([\w_']+)/) { $sub = $1; # print "\nSubroutine: $sub\n"; } # look for use of @_ if (/\@_/) { $atus_used{$sub} = 1; # print "$sub uses \@_\n"; } # look for parameterless procedure call if (/&([\w_']+)\;/) { $proc_call{$1}++; # print "Parameterless call: $1\n"; } if (eof) { $sub = "main"; } } foreach $sub (keys %atus_used) { if ($c = $proc_call{$sub}) { print "$sub called $c times without parameters\n"; } next unless $sub =~ s/[\w_]+'//; # strip package name if ($c = $proc_call{$sub}) { print "$sub called $c times without parameters\n"; } }