Как я могу проверить, возвращает ли подпрограмма * ничего*

#perl #subroutine

#perl #подпрограмма

Вопрос:

Как я могу определить, что функция perl nothing не возвращает даже undef ?

Примеры:

 sub test {
   return;
}
  

или

 sub test {}
  

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

У кого-нибудь есть идея, как я могу проверить значение «null», чтобы я мог создать условное исключение?

Комментарии:

1. Невозможно «ничего не возвращать, даже не отменять»*

2. Опять же, нет способа «ничего не возвращать, даже undef» . Пустой список — это пустой список; это не «ничего», это информация. Возврат «ничего» — странная концепция, которая невозможна на любом языке.

3. Возврат пустого списка означает возврат без размещения чего-либо в стеке. «Возврат пустого списка» — это метафора, которая является синонимом «возврата нулевых скаляров» и «возврата ничего».

Ответ №1:

Если вы используете return и не указываете возвращаемое значение, подпрограмма возвращает пустой список в контексте списка, неопределенное значение в скалярном контексте или ничего в контексте void.

Если не return найдено и если последний оператор является выражением, возвращается его значение. Если последний оператор представляет собой структуру управления циклом, такую как a foreach или a while , возвращаемое значение не указано. Пустой подраздел возвращает пустой список.

perlsub

В обоих ваших случаях он вернет пустой список. Таким образом, вы не можете различать их.

Если я правильно вас понял, вы пытаетесь избежать переопределения пустого списка с помощью 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 если параметры неверны, и вызывающий код может использовать эту информацию по своему усмотрению