注意:この質問に記載されている閉鎖は単なる便利な例です。私が実際に作業しているものは、これよりもかなり複雑です。 IOW、この閉鎖の詳細は無視してください。 AFAICTは、親スコープ内のレキシカル変数を参照するということです。 List::Util::reduce
への呼び出しの最初の引数は、ネストされたクロージャを参照して置き換えられるようにList :: Util :: reduceの最初の引数としてネストされたクロージャを使用する方法?
は、私は以下のサブfoo
を再定義します。
use strict;
use warnings FATAL => 'all';
use List::Util;
sub foo {
my ($x, $y) = @_;
return List::Util::reduce { $y->[ $b ]{ $x } ? $a + (1 << $b) : $a } 0, 0 .. $#$y;
}
私の最初の試みは、このでした:
sub foo {
my ($x, $y) = @_;
sub z {
our ($a, $b);
return exists $y->[ $b ]{ $x } ? $a | (1 << $b) : $a;
}
return List::Util::reduce \&z, 0, 0 .. $#{ $y };
}
...しかし、これはそのVariable "$y" will not stay shared
を言って、警告になります。
これまで私はこの種のエラーが発生していたことを知りましたが、入れ子になったsub
の定義を変数に割り当てられた匿名のサブセットに置き換えることが唯一の方法です。したがって、私はこれを代わりに試しました:
sub foo {
my ($x, $y) = @_;
my $z = sub {
our ($a, $b);
return exists $y->[ $b ]{ $x } ? $a | (1 << $b) : $a;
};
return List::Util::reduce($z, 0, 0 .. $#{ $y });
}
ここでエラーはType of arg 1 to List::Util::reduce must be block or sub {} (not private variable)
と表示されます。
これは本当にわかりません。 reduce
の最初の引数としてサブリファレンスを渡すのはなぜサポートされないのですか?
PSは:
sub foo {
my ($x, $y) = @_;
my $z = sub {
our ($a, $b);
return exists $y->[ $b ]{ $x } ? $a | (1 << $b) : $a;
};
return List::Util::reduce { $z->($a, $b) } 0, 0 .. $#{ $y };
}
...しかし、私が本当に知りたいのですが、(A)(List::Util::reduce
の最初の引数としてSUBREFを使用してと間違って何等がある:以下は動作しませんこの変形をサポートするための技術的な障害? (b)List::Util::reduce
にネストされたクロージャを渡すより直接的なアプローチ({ $z->($a, $b) }
)がありますか?
最後のフォーム 'reduce \&BLOCK、LIST'の使い方は?私は以下を試しました: 'perl -mList :: Util -E 'List :: Util :: reduce \&{$ a> $ b? $ a:$ b}、1..10''となり、セグメント化エラーが発生しました。 –
ブロックは現場で評価され、 '\&{$ z}'のように参照をサブに返さなければなりません – ikegami