Подтвердить что ты не робот

Какая разница между возвратом; и вернуть undef; в Перл

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

return;

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

return undef;

?

4b9b3361

Ответ 1

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

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

Ответ 2

Учитывая

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

Ответ 3

Я думаю, что по-прежнему согласен с PBP.

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

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

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

foo(1, scalar bar(), 2);

Ответ 4

В книге "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().