Perl で名前付きサブルーチンではなく、なぜ匿名サブルーチンを使用することを選択するのか、私はただ興味があります。ありがとう。
7 に答える
「匿名」サブルーチンは、シンボルテーブル内の名前にバインドされていないことを除いて、通常の名前付きサブルーチンに非常に似ています。
sub Foo { stuff() }
BEGIN { *Foo = sub { stuff() } } # essentially equivalent
2番目のケースでは、「匿名」サブルーチンが作成され、現在の名前空間の「Foo」という名前にバインドされます。BEGINブロックは、名前付きサブルーチンの処理方法と同じように、コンパイル時に発生します。(最初のケースでは、スタックトレースに表示される名前が付けられているため、少し複雑です。)
匿名サブルーチンは、実行時に関数を作成するときにいつでも役立ちます。これは、「クロージャ」(字句コンテキストを「記憶」する関数)に特に適しています。たとえば、リストをイテレータに変換します。
use 5.010;
use strict;
use warnings;
sub make_iterator {
my @list = @_;
return sub { shift @list }; # new sub that 'remembers' @list
}
my $iter1 = make_iterator( 0 .. 10 );
my $iter2 = make_iterator( 'a' .. 'z' );
say $iter1->(); # '0'
say $iter1->(); # '1'
say $iter2->(); # 'a'
匿名サブルーチンが役立つ理由の詳細については、 Perlでの関数型プログラミングのさまざまな手法とアプリケーションについて説明している「高次Perl 」という本をお勧めします。
匿名サブルーチンについて、そしてPerl をマスターする でそれらを使用する理由について説明します。つまり、文字列や数値について考えるのと同じように、動作をデータの別の形式として考えるようになります。そのアイデアに慣れていれば、非常に驚くべきことを実行できます。なぜなら、多くの決定をプログラムの非常に遅い段階まで進めることができるからです。現れるかもしれません。
サブルーチンを実行することを知っているコードを書くことができますが、まだどのサブルーチンかはわかりません。前の手順を信頼して、それを解決してください。それができるようになると、プログラムを作成するためのコードを書いているような別のレベルのプログラミングになります。一部のプログラミングの問題は、この方法で簡単に解決できます。
そして、他のすべての機能と同様に、これをやりすぎたり、不適切に使用したりする可能性があります。
最初:サブのものはサブです。my $thing=sub... は、変数に格納されたサブ参照です。
2 番目: 微妙な使い方の違いがあります。
use strict;
use warnings;
sub xx {
my $zz=1;
sub yy {
print $zz;
}
}
perl tmp.pl
Variable "$zz" will not stay shared at tmp.pl line 8.
sub yy
[ ...] を [ my $yy = sub {
...] または [ ...] に変更するlocal *yy = sub{
と、苦情がなくなります。
また、正直なところ、@x=(1,2,3) と $x=[1, 2, 3] の比較と同じように、subs への参照は扱いが簡単です。
これは、Nasmのversion.plを書き直した例です。
# jump table to subroutines / variables
my %jump = (
id => 'id',
xid => 'xid',
hex_id => 'xid',
h => \&h,
mac => \&mac,
sed => \&sed,
make => \&make,
nsis => \&nsis,
perl => \&perl,
dump => \&perl,
yaml => \&yaml,
yml => \&yaml,
json => \&json,
js => \&json,
help => \&help,
usage => sub{
require Pod::Usage;
Pod::Usage::pod2usage(
"run perldoc $0 or pod2text $0 for more information"
);
}
);
基本的に私が考えることができる唯一の理由は、カルバックまたはジャンプテーブルのためです。