Почему в этом случае работает автовификация Perl? - PullRequest
3 голосов
/ 19 ноября 2009

Может ли кто-нибудь помочь мне понять вывод этой 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);

И вывод:

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

Откуда исходит "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);

мой вывод - это то, что я ожидаю:

foo

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

EDIT: Я знаю, что use strict; поймает это, но мне больше интересно знать, как строка "foo" все еще печатается.

Ответы [ 4 ]

17 голосов
/ 19 ноября 2009

Ваш код отсутствует

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.

Убедитесь, что все ваши скрипты начинаются с:

use strict;
use warnings;

Дано:

$hash{hello} = "foo";

$hash{hello} - это НЕ ссылка на хеш.

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

обрабатывает строку "foo" как ссылку на хэш и создает хэш %main::foo и устанавливает $foo{world} в "bar".

Когда вы делаете:

print Dumper \%hash;

печатает только содержимое %hash. Принимая во внимание, когда вы делаете

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

печатает $foo{world}.

Без strict вы не сможете обнаружить, что скрипт растоптал все пространство имен пакета.

Добавить

print Dumper \%main::;

или

print Dumper \%main::foo;

для проверки таблицы символов после ее запуска.

2 голосов
/ 19 ноября 2009

В основном строка "foo" является единственным значением %hash, но (из-за отсутствия строгости) создается% foo, содержащее (world => "bar")

1 голос
/ 19 ноября 2009

Автовивификация работает только тогда, когда вы начинаете с неопределенными значениями. Поскольку ваш $hash{hello} не является неопределенным значением, вы не можете автоматически выбрать следующий уровень. Вместо этого вы в конечном итоге используете $hash{hello} в качестве мягкой ссылки.

1 голос
/ 19 ноября 2009

Если вы используете строгий, вы получите ошибку с вашим скриптом.

Нельзя использовать строку ("foo") в качестве ссылки HASH, в то время как "строгие ссылки" используются в ...

...