开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜