created: 2023-09-06T03:01:10.359Z
perlでコードブロックの中で任意の $_ を参照させる
ライブラリなどで、渡したコードブロックの中で $_
に任意の値が代入されている状態で処理をさせるコードがある。
たとえば、FormValidator::Lite
のルールを記述する際には、引数で渡した値が $_
に入った状態で処理を記述できる。
rule LESS_THAN => sub {
$_ < $_[0];
};
↑の例は「引数で渡した値が、リクエストパラメータよりも小さい数値か」を判定するコードだが、リクエストパラメータに $_
としてアクセスさせるようになっている。
どうやればいいか
このようなコードブロックは local
を使って実現する。
sub main {
# $_ を利用しているコードブロック
my $obj = {cb => sub { warn $_->{test} }};
# local を使うと、このスコープ内でこれ以降呼ぶ関数は$_がセットされる
local $_ = {test => 1};
$obj->{cb}->();
# $_ の値のリセットはこうやる
local $_;
$obj->{cb}->();
}
書いてある
A local modifies its listed variables to be "local" to the enclosing block, eval, or do FILE--and to any subroutine called from within that block.
重要なところだけもう一度引用する。
any subroutine called from within that block.
いままで local
を使うと「そのスコープ内で変数を変更してくれる」というものだと思っていたが、スコープというよりも「より深いコールスタックで」というふうに理解した方がよいのかもしれない。