开发者

Why does Perl's autovivification work in this case?

Can some one help me understand the output of this Perl program:

use Data::Dumper;
my %hash;
$hash{hello} = "foo";
$hash{hello}{world} = "bar";
print $hash{hello} . "\n";
print $hash{hello}{world} . "\n";
print Dumper(\%hash);

And the output:

foo
bar
$VAR1 = {
          'hello' => 'foo'
        };

Where is the "foo" coming from? How come it isn't printed out by dumper?

Note that if I swap the order of the assignments:

use Data::Dumper;
my %hash;
$hash{hello}{world} = "bar";
$hash{hello} = "foo";
print $hash{hello} . "\n";
print $hash{hello}{world} . "\n";
print Dumper(\%hash);

my output is what I ex开发者_StackOverflowpect:

foo

$VAR1 = {
          'hello' => 'foo'
        };

EDIT: I know that use strict; would catch this, but I'm more interested in know how the string "foo" is still being printed.


Your code is missing

use strict;
C:\Temp> hui
Can't use string ("foo") as a HASH ref while "strict refs" in use at 
C:\Temp\hui.pl line 7.

Make sure all your scripts start with:

use strict;
use warnings;

Given:

$hash{hello} = "foo";

$hash{hello} is NOT a hash reference.

$hash{hello}{world} = "bar";

treats the string "foo" as a hash reference and creates the hash %main::foo and sets $foo{world} to "bar".

When you do:

print Dumper \%hash;

it only prints the contents of %hash. Whereas, when you do

print $hash{hello}{world} . "\n";

it prints $foo{world}.

Without strict, you do not get to find out that the script has trampled all over the package name space.

Add a

print Dumper \%main::;

or

print Dumper \%main::foo;

to inspect the symbol table after you run this.


Basically the string "foo" is the only value of %hash, but (due to non-strictyness) %foo is being created that contains (world => "bar")


If you were using strict, you'd get an error with your script.

Can't use string ("foo") as a HASH ref while "strict refs" in use at ...


Autovivification only works when the you start with undefined values. Since your $hash{hello} isn't an undefined value, you don't autovivify the next level. Instead, you end up using $hash{hello} as a soft reference.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜