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: [email protected] (Bob Mackay)
Subject: Re: Global behavior of @_  (??)
Message-ID: <[email protected]>
Sender: [email protected]
Nntp-Posting-Host: max.cpd.tandem.com
Reply-To: [email protected]
Organization: Tandem Computers Inc.
References: <[email protected]>
Date: Wed, 18 Aug 1993 22:14:09 GMT
Lines: 121

In article [email protected], [email protected] (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
     \   \__/  /       |         [email protected]
      \_______/        |





#!/usr/local/bin/perl
################################################################################
#
# ATUS - AT UnderScore checker - Bob Mackay - [email protected]
#
# 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";
   }

}