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";
}
}