Hint: clobbered? or assigned? | [reply] |
I'm using perl, v5.8.1-RC3 built for darwin-thread-multi-2level, and sometimes the variables do get clobbered (rather than assigned). The explanation you're looking for is that
each array variable is assigned the value ${@_}.
BEGIN is called with no arguments, so @_ is empty. ${@_} puts @_ in scalar context so @_ evaluates to the number of its elements, which is 0.
So each array variable is being assigned the value of $0 which is the name of the source file. The while loop reads each line of the source file and sets @_ to the array consisting of that line. At the end of the loop @_ contains only the last line of the file, which evals to 1 and prints the JAPH message as a side effect. The second half of the || should never be executed.
The problem with this explanation is that the order of the variables in %:: is not fixed. Once you set @_ to $0 it is no longer empty, so any subsequent assignments are taken from $1 which is undefined. I've extended your code to print the assignments it's making as they happen:
LINE: while ( defined( $_ = <ARGV> ) ) {
@_ = $_;
}
sub BEGIN {
foreach $_ (%main::) {
print "\@{$_}='${@_}'\n";
eval '@{$_}=${@_}';
}
}
{
print "Just another perl hacker.\n" unless eval "@_";
}
I realize this messes up your carefully-designed layout, but eval "}\n" seems to evaluate to a false value, so it still prints the JAPH message. Here's partial output from one less-successful run:
@{STDIN}='dedalus.pl.tdy'
@{*main::STDIN}='dedalus.pl.tdy'
...
@{_}='dedalus.pl.tdy'
@{*main::_}=''
...
@{ARGV}=''
@{*main::ARGV}=''
...
Can't open : No such file or directory at dedalus.pl.tdy line 1.
Just another perl hacker.
|
The following modification of your code seems to work reliably here:
#! /usr/bin/perl -n
@_=$_}BEGIN{eval'@{$_}=${@_}'for sort keys%::}{eval"@_"||
print "Just another perl hacker.\n"
| [reply] [d/l] [select] |