Perl Advent Calendar 2022 の 12日目です。
qiita.com
こういうときのことです。
sub func2 { # ここのコンテキスト } sub func1 { func2; }
サブルーチンのコンテキストは wantarray - Perldoc Browser を使うと調べられそうです。 wantarray
は、 list/scalar/void コンテキストでそれぞれ true/false/undef (値としては 1
''
undef
) を返します。
Returns true if the context of the currently executing subroutine or eval is looking for a list value. Returns false if the context is looking for a scalar. Returns the undefined value if the context is looking for no value (void context).
https://perldoc.perl.org/functions/wantarray
こういう感じで、呼び出し方を変えながら wantarray
を見るコードを実行すると:
use feature qw(say); sub print_wantarray { my $wa_str = defined wantarray ? (wantarray ? 'true' : 'false') : 'undef'; say " wantarray: $wa_str\n"; } sub func1 { print_wantarray; } say 'my $val1 = [print_wantarray];'; my $val1 = [print_wantarray]; say 'my $val2 = print_wantarray;'; my $val2 = print_wantarray; say 'print_wantarray;'; print_wantarray; say 'my $val3 = [func1];'; my $val3 = [func1]; say 'my $val4 = func1;'; my $val4 = func1; say 'func1;'; func1;
こうなります。前半は print_wantarray
を直接呼んだものですが、後半の func1
を介した呼び出しでも同じコンテキストになっています。同僚と、そういえばこれどうなるんだろう、という会話になり試しましたが、子の戻り値が結局親の戻り値になるので、コンテキストが同じになるのはたしかにそういうものか、という感じで納得でした。
$ perl a.pl my $val1 = [print_wantarray]; wantarray: true my $val2 = print_wantarray; wantarray: false print_wantarray; wantarray: undef my $val3 = [func1]; wantarray: true my $val4 = func1; wantarray: false func1; wantarray: undef
ちなみに return - Perldoc Browser を省略して書いていますが、明示的に書いても同じです。 return
によってコンテキストが変わったりしないのかな、と思ったら、むしろ return
がコンテキストに合わせる立場でした (コンテキストによって返す値が変わりますと書かれている)。
Evaluation of EXPR may be in list, scalar, or void context, depending on how the return value will be used, and the context may vary from one execution to the next (see wantarray).
https://perldoc.perl.org/functions/return