假设我有以下代码:
my $compiled = eval 'sub { print( "Hello World\n" ); }';
我可以这样写:
$compiled->();
到现在为止还挺好.现在假设我创建了10个函数:
my @fns = (); for ( my $i = 0; $i < 10; $i++ ) { push( @fns,eval "sub { print( 'I am function $i\n' ); }" ); }
foreach ( @fns ) { $_->(); }
现在,我想创建一个动态函数,它可以显式调用我的10个函数中的每一个:
my $evalcode = "sub {"; foreach ( @fns ) { # if I print $_ it shows something like # "CODE(0x94084f8)",but trying to # call "CODE(0x94084f8)->()" is invalid $evalcode .= "$_->();"; } $evalcode .= "}"; my $dynamic_fn = eval $evalcode; $dynamic_fn->();
是否可以对子例程进行字符串化引用并直接调用它?
PS为什么,你问?因为我想编写一个动态例程,构造一个if(m /…/){} elsif(m /…/){} …链,然后根据输入字符串调用动态函数.
解决方法
您可能希望使用常规的词法闭包,而不是字符串evals:
my @functions; for my $i (0 .. 9) { push @functions,sub { print "I am function $i\n" }; } my $call_all_funcs = sub { for my $func (@functions) { $func->(); } }; $call_all_funcs->();
也可以根据其地址检索代码引用,但这样更复杂,更难理解,并且通常不是一个好主意.