为什么Perl的autovivification在这种情况下有效?

tst*_*ter 3 perl autovivification

有人可以帮助我理解这个Perl程序的输出:

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

并输出:

foo
bar
$VAR1 = {
          'hello' => 'foo'
        };
Run Code Online (Sandbox Code Playgroud)

"foo"来自哪里?怎么没有翻斗车打印出来?

请注意,如果我交换作业的顺序:

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

我的输出是我所期望的:

foo

$VAR1 = {
          'hello' => 'foo'
        };
Run Code Online (Sandbox Code Playgroud)

编辑:我知道use strict;会抓住这个,但我更感兴趣的是知道如何打印字符串"foo".

Sin*_*nür 17

你的代码丢失了

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

确保所有脚本都以:

use strict;
use warnings;
Run Code Online (Sandbox Code Playgroud)

鉴于:

$hash{hello} = "foo";
Run Code Online (Sandbox Code Playgroud)

$hash{hello}NOT散列引用.

$hash{hello}{world} = "bar";
Run Code Online (Sandbox Code Playgroud)

将字符串"foo"视为哈希引用并创建哈希%main::foo并设置$foo{world}"bar".

当你这样做时:

print Dumper \%hash;
Run Code Online (Sandbox Code Playgroud)

它只打印内容%hash.然而,当你这样做的时候

print $hash{hello}{world} . "\n";
Run Code Online (Sandbox Code Playgroud)

它打印$foo{world}.

没有strict,你不会发现脚本已经遍布包名称空间.

添加一个

print Dumper \%main::;
Run Code Online (Sandbox Code Playgroud)

要么

print Dumper \%main::foo;
Run Code Online (Sandbox Code Playgroud)

运行此命令后检查符号表.

  • 正在发生的事情是它正在激活一个名为`%foo`的变量(因为当你使用字符串作为参考时会发生这种情况).在代码末尾添加`print Dumper(\%foo)`以查看危险结果. (3认同)
  • 添加use strict会发现问题,但它并没有告诉我我是如何获得输出的.这更像是一个Perl内部问题而不是"plz修复我的代码" (2认同)