Есть ли разница между подпрограммой, которая делает
return;
и тот, который делает
return undef;
?
Есть ли разница между подпрограммой, которая делает
return;
и тот, который делает
return undef;
?
return;
возвращает пустой список в контексте списка, но undef
в скалярном контексте. return undef;
всегда будет возвращать единственное значение undef
даже в контексте списка.
Как правило, обычно не рекомендуется return undef;
из подпрограммы, обычно используемой в контексте списка:
sub foo { return undef }
if ( my @x = foo() ) {
print "oops, we think we got a result";
}
Как правило, обычно не рекомендуется return;
из подпрограммы, обычно используемой в скалярном контексте, потому что она не будет вести себя так, как пользователь ожидает в контексте списка:
sub foo { return }
%x = ( 'foo' => foo(), 'bar' => 'baz' );
if ( ! exists $x{'bar'} ) {
print "oops, bar became a value, not a key";
}
Обе эти ошибки происходят на практике довольно много, тем более, что, возможно, потому, что субмарины, которые, как ожидается, возвращают скаляр, более распространены. И если ожидается, что он вернет скаляр, ему лучше вернуть скаляр.
Учитывая
sub foo { return; }
sub bar { return undef; }
В скалярном контексте они ведут себя одинаково.
my $foo = foo(); # $foo is undef
my $bar = bar(); # $bar is undef
В контексте списка они ведут себя по-разному
my @foo = foo(); # @foo is () (an empty list)
my @bar = bar(); # @bar is ( undef ) (a one-element list)
Обратите внимание, что одноэлементный список является истинным значением в булевом контексте, хотя единственный элемент undef
.
В общем, обычно это не очень хорошая идея для return undef;
из подпрограммы из-за того, как она ведет себя в контексте.
Я думаю, что по-прежнему согласен с PBP.
1) Вы должны избегать вызовов функций вложенности:
my $result = bar();
foo(1, $result, 2);
2) Вы всегда должны быть явными (при выполнении "сложных" вещей):
foo(1, scalar bar(), 2);
В книге "Perl Best Practices" рекомендуется использовать return;
вместо return undef;
, потому что последний вернет одноэлементный список в контексте списка (другие ответы уже упоминают об этом). Это было бы "неприятной ошибкой" в соответствии с книгой.
Однако, я думаю, что возвращение ничего не может привести к серьезным ошибкам (возможно, их трудно найти), тогда как вызов логической функции в контексте списка кажется довольно простым для отладки.
Поэтому я всегда возвращаю что-то (что оценивает) false в моих логических функциях (обычно 0 для false и 1 для true).
(Да, это также вернет одноэлементный список в контексте списка, так что комментарий в книге технически прав - но тогда фактическая ошибка будет вызывать булевскую функцию в контексте списка.)
Чтобы быть ясным, я по-прежнему рекомендую книгу. Он предлагает много хороших советов.
И я имею в виду главу 9 (Подпрограммы), стр. 199/200 ( "Использовать голый возврат для возврата отказа" ) в книге "Perl Best Practices" Дамиана Конвей (O'Reilly Media, Inc.), ISBN 978 -0-596-00173-5. Не уверен, есть ли другая/более новая версия.
Боковое примечание:
Кажется, Perl возвращает пустую строку, когда что-то отрицает. my $foo = 5; return !$foo;
возвращает q().