#perl #subroutine
#perl #подпрограмма
Вопрос:
Как я могу определить, что функция perl nothing
не возвращает даже undef
?
Примеры:
sub test {
return;
}
или
sub test {}
Проблема в том, что любопытная действующая функция также может возвращать строки, списки, … и является частью внешнего пакета. Поэтому я не могу проверить, test() || undef
потому что пустые списки или строки будут заполнены undef
.
У кого-нибудь есть идея, как я могу проверить значение «null», чтобы я мог создать условное исключение?
Комментарии:
1. Невозможно «ничего не возвращать, даже не отменять»*
2. Опять же, нет способа «ничего не возвращать, даже undef» . Пустой список — это пустой список; это не «ничего», это информация. Возврат «ничего» — странная концепция, которая невозможна на любом языке.
3. Возврат пустого списка означает возврат без размещения чего-либо в стеке. «Возврат пустого списка» — это метафора, которая является синонимом «возврата нулевых скаляров» и «возврата ничего».
Ответ №1:
Если вы используете
return
и не указываете возвращаемое значение, подпрограмма возвращает пустой список в контексте списка, неопределенное значение в скалярном контексте или ничего в контексте void.Если не
return
найдено и если последний оператор является выражением, возвращается его значение. Если последний оператор представляет собой структуру управления циклом, такую как aforeach
или awhile
, возвращаемое значение не указано. Пустой подраздел возвращает пустой список.
В обоих ваших случаях он вернет пустой список. Таким образом, вы не можете различать их.
Если я правильно вас понял, вы пытаетесь избежать переопределения пустого списка с помощью undef, если вы это сделаете test () || undef
. Но это не имеет значения. В Perl как пустой список, так и undef считаются ложными.
Все приведенные ниже значения равны false
0
'0'
undef
'' # Empty scalar
() # Empty list
('')
Ответ №2:
Невозможно «ничего не возвращать, даже не отменять»*
Подпрограмма test
, которую вы описываете, оценивается undef
, если вы вызываете ее как
my $ret = test();
или пустой список, если вы вызываете его как
my @ret = test();
То, что вы делаете с этим, зависит от того, какие допустимые значения может вернуть ваша подпрограмма. Предназначен ли он для возврата списка или скаляра?
Очевидно, что условие ошибки должно отличаться от любого допустимого возвращаемого значения, и обычным способом является всегда возвращать скалярное значение, которое может быть ссылкой, если вам нужно вернуть несколько значений
Предположим, у вас есть подпрограмма корзины, которая возвращает список всех значений в заданном диапазоне
use strict;
use warnings;
BEGIN { require v5.10 }
use feature 'say';
STDOUT->autoflush;
sub range {
my ($start, $end) = @_;
return if $end < $start;
return [ $start .. $end ];
}
my $range = range(1, 3) or die;
say for @$range;
$range = range(10, 1) or die;
say for @$range;
вывод
1
2
3
Died at E:Perlsourcetwice.pl line 19.
Возвращаемое значение — это undef
если параметры неверны, и вызывающий код может использовать эту информацию по своему усмотрению