Is this Perl's bug in interpretation?
11 package C;
12 $_ = 5;
13 print "$_\n$C::_\n$::_\n";
output:
5
5
As we know $_
is a super global variable in Perl,but why the first assignment to this variable will cause assignment to $::_
at the same time?
UPDATE
package C;
$_ = 5;
print "$_\n$C::_\n$::_\n";
package main;
print "####in main::\n";
$_ = 2;
print "$_\n$::_\n";
package A;
our $_ = 1;
$_ = 4;
print "####in A::\n";
print "$_\n$::_\n$A::_\n";
print "####in B:开发者_开发技巧:\n";
package B;
$_ = 3;
print "| $_ | \n
|$::_ | \n
|$B::_\n";
in the last print
,you can see that $_
and $::_
is different.
| 3 |
|2 |
|
$_
is kept in package main
. Also, if package name is omitted, the main
package is assumed. That is, $::_
is equivalent to $main::_
(as well as to $main'_
).
Regarding your update: $_
is supposed to be $main::_
. But after the our
, $_
is now looking at $A::_
. This seems to be a bug in Perl 5.8.8.
The line $_ = 3;
is treated like $A::_ = 3;
instead of $::_ = 3
. This seems to be bug in version 5.8.8.
When run in the debugger, the line
our $_ = 1;
creates a package variable $A::_
as can be seen in the debugger.
DB<5> V :: _
$_ = 2
@_ = (
0 0
1 '_'
2 *main::_
3 0
4 '-1'
)
DB<6> V A:: _
$_ = 1
the next line $_ = 4;
modifies $A::_
.
When the line $_ = 3;
is executed, the package variable $A::_
is set. This is also buggy. It should access $::_
. This is the debugger output at that point:
DB<7> V :: _
$_ = 2
@_ = (
0 0
1 '_'
2 *main::_
3 0
4 '-1'
)
DB<8> V A:: _
$_ = 3
I hope this shows what is going on.
By default, $_
is short for $::_
, as you've demonstrated.
However, in your part of the code in your update, you've changed what $_
means by creating a lexical named $_
. This lexical is being used in the case you are asking about.
our $x
creates a lexical variable $x
aliased to the current package's $x
, except for "super globals". For "super globals", the new variable is aliased to the "super global".
>perl5140 -le"package PA; our $x='A'; package PB; $x='B'; print $PA::x;"
B
>perl5140 -le"package PA; our $_='A'; package PB; $_='B'; print $::_;"
B
It seems that exception didn't exist in 5.8.
By the way, do you realise that 5.8 and 5.10 are officially end-of-lifed?
::foo
is equivalent to main::foo
and main::
is where punctuation variables as $_
are stored.
精彩评论