はreturn $foo if $bar
と同等$bar and return $foo
です。したがって、$bar
が false の場合、このステートメントは の値に評価されます$bar
。サブルーチンは最後に実行されたステートメントの値を返すため、サブルーチンが定義されている場合は値を返し、$var
定義されていない場合は偽の値を返します。
明示的なルートに移動して、別のリターンをそこに置くことができます。
# all branches covered
return $var if defined $var;
return;
これは愚かで、 と同等return $var
です。
これで、 sub が返す偽の値が実際に定義されたので、に割り当てられ$a
ます。代わりに、真実をテストできます。
$a = $tmp if $tmp;
…しかし、それはワームの別の缶を開きます.
戻り値は、それらが必要な戻り値なのかエラー インジケーターなのかを伝えるのが非常に苦手です。それを回避する2つのクリーンな方法があります:
関数が正常に終了したかどうかを示す 2 番目の値を返します。
sub func {
my $var;
return (1, $var) if defined $var;
return (0); # not strictly needed
}
my ($ok, $tmp) = func();
$a = $tmp if $ok;
(基本的には、Golang で見られるコンマ OK イディオム)
実際の戻り値を取得するために分解する必要があるコンテナーを返します。可能性としてはundef
、エラー時に (または何か false を) 返すか、そのような値が存在する場合はその値へのスカラー参照を返すことです:
sub func {
my $var;
return \$var if defined $var;
return undef; # actually not needed
}
my $tmp = func();
$a = $$tmp if defined $tmp;
(基本的にMaybe
は Haskell で見られる型)
明白な一時変数なしでそれを使用する方法は次のとおりです。
($a) = map { $_ ? $$_ : () } func(), \$a;