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: <CBz73q.FwD@tandem.com>
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";
    }
    
}