В чем разница между возвращением; и вернуть undef; в Perl - PullRequest
26 голосов
/ 08 августа 2010

Есть ли разница между подпрограммой, которая делает

return;

и тот, который делает?

return undef;

Ответы [ 4 ]

48 голосов
/ 08 августа 2010

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";
}

Обаиз этих ошибок на практике встречается совсем немного, а последний - тем более, возможно, потому, что подпрограммы, которые, как ожидается, вернут скаляр, встречаются чаще.И если ожидается, что он вернет скаляр, лучше вернуть скаляр.

21 голосов
/ 08 августа 2010

Учитывая

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; из подпрограммы обычно не очень хорошая идея из-за ее поведения в контексте.

2 голосов
/ 30 марта 2014

В книге "Perl Best Practices" рекомендуется использовать return; вместо return undef;, поскольку последний возвращает список из одного элемента в контексте списка (другие ответы уже упоминали об этом). Это будет «неприятная ошибка», согласно книге.

Однако я думаю, что возврат ничего не может на самом деле вызвать серьезные ошибки (вероятно, трудно найти), тогда как вызов логической функции в контексте списка кажется довольно простым для отладки.

Так что я всегда возвращаю что-то (что оценивается как) false в моих логических функциях (обычно 0 для false и 1 для true).
(Да, это также вернет список из одного элемента в контексте списка - так что комментарий в книге технически верен - но тогда настоящей ошибкой будет вызов логической функции в контексте списка.)

Для ясности, я все еще рекомендую книгу. Он предлагает много полезных советов.
И я имею в виду главу 9 (Подпрограммы), стр. 199/200 («Использовать простой возврат для возврата».) В книге «Лучшие практики Perl» Дамиана Конвея (O'Reilly Media, Inc.), ISBN 978 -0-596-00173-5. Не уверен, что есть другое / более новое издание.

Примечание:
Perl, похоже, возвращает пустую строку при отрицании чего-либо. my $foo = 5; return !$foo; возвращает q().

2 голосов
/ 10 августа 2010

Думаю, я все еще согласен с PBP.

1) Вы должны избегать вложенных вызовов функций:

my $result = bar();
foo(1, $result, 2);

2) Вы всегда должны быть явными (при выполнении «сложных» вещей):

foo(1, scalar bar(), 2);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...