Вы тестируете неопределенное значение для числового нуля.Конечно, вы получите истинный результат!Чего ты ожидал?
Вы также должны получить предупреждение под use warnings
.Почему не так?
Если вы не запускаете программу с:
use v5.12; # or whatever it is you are using
use strict;
use warnings;
, вам действительно не стоит об этом беспокоиться.:)
РЕДАКТИРОВАТЬ
Примечание: я только уточняю для правильности, потому что строки комментариев не годятся для этого.Мне действительно было наплевать на то, что кто-то чуть-чуть пофиг на очки репутации.Я просто хочу, чтобы люди поняли.
Даже в модуле CPAN autovivification
ничего не меняется.Свидетель:
use v5.10;
use strict;
use warnings;
no autovivification;
my %md_hash = ();
$md_hash{top}{primary}{secondary} = 0;
if ($md_hash{top}{foobar}{secondary} == 0) {
say "yup, that was zero.";
}
При запуске это говорит:
$ perl /tmp/demo
Use of uninitialized value in numeric eq (==) at /tmp/demo line 10.
yup, that was zero.
Тест - оператор ==
.Его RHS 0
.Его LHS составляет undef
независимо от автовивификации .Поскольку undef
численно 0
, это означает, что как LHS, так и RHS содержат 0
, который ==
правильно идентифицирует как содержащий одно и то же число.
Автовивификация здесь не является проблемой, так как ysthправильно замечает, когда пишет: «Это не многомерный вопрос, специфичный для хеша». Все, что имеет значение, это то, что вы передаете ==
.И undef
численно 0
.
Вы можете остановить автовыведение, если действительно, действительно хотите - используя прагму CPAN.Но вам никогда не удастся изменить то, что здесь происходит, подавив autoviv.Это показывает, что это не вопрос автовива, а всего лишь undef
.
Теперь вы получите дополнительные «ключи» при этом, так как неопределенное значение lvalue будетбыть заполненным на пути через цепочку разыменования.Они обязательно должны быть одинаковыми:
$md_hash{top}{foobar}{secondary} # implicit arrow for infix deref
$md_hash{top}->{foobar}->{secondary} # explicit arrow for infix deref
${ ${ $md_hash{top} }{foobar} }{secondary} # explicit prefix deref
Всякий раз, когда вы переоцениваете lvaluable undef
в Perl, это хранилище всегда заполняется надлежащим видом ссылки на недавно выделенный объект.анонимный референт соответствующего типа.Короче говоря, это autovivs .
и , что вы можете остановить, подавляя или же обходя autoviv.Однако отрицание autoviv - это не то же самое, что обходить его стороной, потому что вы просто изменяете, что возвращается.Общее выражение по-прежнему полностью оценивается: нет автоматического короткого замыкания только потому, что вы подавляете autoviv.Это потому, что с autoviv нет проблем (и если бы его там не было, вы бы очень раздражались: поверьте мне).
Если вы хотите замкнуть накоротко, вы должны написать это сами.Я никогда не нуждаюсь в себе.В Perl это так.С другой стороны, программисты на С довольно привыкли писать
if (p && p->whatever) { ... }
И поэтому вы тоже можете это делать, если хотите.Однако, по моему собственному опыту, это довольно редко.Вы почти должны ошибаться в Perl, чтобы это когда-либо имело значение, поскольку ваш код не довольно легко изменить, чтобы он действовал, если есть пустые уровни.