- PVSM.RU - https://www.pvsm.ru -
Посмотрим на код:
use strict;
use warnings;
sub mysub($$)
{
my ($a, $b) = @_;
print "$an";
print "$bn";
}
my $x = undef;
mysub($x && $x->[0] =~ /abc/, $x = []);
Может ли mysub в качестве первого аргумента получить нечто, что в boolean контексте является истинной?
Казалось бы нет, ведь для этого $x должен быть ссылкой на массив, а его первый элемент должен содержать подстроку 'abc'
Но оказалось, что может
$perl poc.pl
ARRAY(0xdb6d48)
ARRAY(0xdb6d48)
В чём же дело?
Таким образом когда расчитывается первый аргумент
$x && $x->[0] =~ /abc/
$x является undef т.е. false, следовательно вместо первого аргумента передаётся сам $x,
когда расчитывается второй аргумент, $x присваивается значение [] (ссылка на пустой массив), таким образом когда начинает выполняться код mysub, оба аргумента
содежрат ссылку на $x (которая является пустым массивом)
Если кажется, что код выглядит не очень применимым на практике, то могу сказать что баг был найден в реальном коде unit теста:
ok( ($errors && ($errors->[0] =~ /My Exception/i)), "should catch exception $errors->[0]" );
(при этом срабатывает ещё одна замечательная фича перла Autovivification [1] — если обратиться к $errors->[0] то $error->[0] создастся,
если $error был до этого undef)
Автор: vsespb
Источник [2]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/26546
Ссылки в тексте:
[1] Autovivification: http://en.wikipedia.org/wiki/Autovivification
[2] Источник: http://habrahabr.ru/post/168559/
Нажмите здесь для печати.