Ответ 1
Резюме
- Логические тесты
- Увеличение или уменьшение значения undefined
- Добавление к значению undefined
- Autovivification
- Другие мутаторы
Логические тесты
В соответствии с документацией perlsyn,
Число
0
, строки'0'
и''
, пустой список()
иundef
все ложные в булевом контексте. Все остальные значения верны.
Поскольку значение undefined равно false, следующая программа
#! /usr/bin/perl
use warnings;
my $var;
print "A\n" if $var;
$var && print "B\n";
$var and print "C\n";
print "D\n" if !$var;
print "E\n" if not $var;
$var or print "F\n";
$var || print "G\n";
выводит D
через G
без предупреждений.
Увеличение или уменьшение значения undefined
Нет необходимости явно инициализировать скаляр до нуля, если ваш код будет увеличивать или уменьшать его хотя бы один раз:
#! /usr/bin/perl
use warnings;
my $i;
++$i while "aaba" =~ /a/g;
print $i, "\n";
Приведенный выше код выводит 3
без предупреждений.
Добавление к значению undefined
Подобно неявному нулю, нет необходимости явно инициализировать скаляры в пустой строке, если вы добавите ее хотя бы один раз:
#! /usr/bin/perl
use warnings;
use strict;
my $str;
for (<*>) {
$str .= substr $_, 0, 1;
}
print $str, "\n";
Autovivification
Одним из примеров является "автовивитация". Из Статья в Википедии:
Автовивификация является отличительной чертой языка программирования Perl, включающего динамическое создание структур данных. Автовивитация - это автоматическое создание ссылки на переменные, когда значение undefined разыменовывается. Другими словами, автовивитация Perl позволяет программисту ссылаться на структурированную переменную и произвольные подэлементы этой структурированной переменной, не объявляя заранее о существовании переменной и ее полной структуры.
Например:
#! /usr/bin/perl
use warnings;
my %foo;
++$foo{bar}{baz}{quux};
use Data::Dumper;
$Data::Dumper::Indent = 1;
print Dumper \%foo;
Даже если мы явно не инициализируем промежуточные ключи, Perl заботится о строительных лесах:
$VAR1 = { 'bar' => { 'baz' => { 'quux' => '1' } } };
Без автообвинения код потребует больше шаблонов:
my %foo;
$foo{bar} = {};
$foo{bar}{baz} = {};
++$foo{bar}{baz}{quux}; # finally!
Не путайте автовивитацию со значениями undefined, которые она может произвести. Например,
#! /usr/bin/perl
use warnings;
my %foo;
print $foo{bar}{baz}{quux}, "\n";
use Data::Dumper;
$Data::Dumper::Indent = 1;
print Dumper \%foo;
получаем
Use of uninitialized value in print at ./prog.pl line 6. $VAR1 = { 'bar' => { 'baz' => {} } };
Обратите внимание, что промежуточные ключи автогенерируются.
Другие примеры автовивитации:
-
ссылка на массив
my $a; push @$a => "foo";
-
ссылка на скалярный
my $s; ++$$s;
-
ссылка на хэш
my $h; $h->{foo} = "bar";
К сожалению, Perl не (пока!) автогенерирует следующее:
my $code;
$code->("Do what I need please!");
Другие мутаторы
В ответе на аналогичный вопрос, ysth сообщает
Некоторые операторы преднамеренно опускают "неинициализированное" предупреждение для вашего удобства, потому что они обычно используются в ситуациях, когда значение 0 или "" по умолчанию для левого или единственного операнда имеет смысл.
Это:
++
и--
(до или после),+=
,-=
,.=
,|=
,^=
,&&=
,||=
.
Будучи "определенным" или "//=
, с радостью изменяет значение undefined без предупреждения.