use v5.10;
use Sub::Current;
sub countdown {
state $count = 10;
say $count;
return if --$count < 0;
ROUTINE->();
};
countdown();
你也许想要把这样的代码引用定义为一条单独的语句,即使你不需要这么做.比如你想要把代码引用定义在参数列表中:
use v5.10;
use Sub::Current;
sub run { $_[0]->() };
run( sub {
state $count = 10;
say $count;
return if --$count < 0;
ROUTINE->();
}
);
你也许还需要把子程序作为返回值定义在一条语句中:
use v5.10;
use Sub::Current;
sub factory {
my $start = shift;
sub {
state $count = $start;
say $count;
return if --$count < 0;
ROUTINE->();
}
};
factory(4)->();
使用这个模块的缺点就是对CPAN的依赖,虽然它是个很轻量级的.还有另一个模块, Devel::Caller,由Richard Clamp编写.它可以获得调用栈中在任意层级的代码引用,包括当前层级:
use v5.10;
use Devel::Caller qw(caller_cv);
sub factory {
my $start = shift;
sub {
state $count = $start;
say $count;
return if --$count < 0;
caller_cv(0)->();
}
};
factory(7)->();
Perl 5.16可以让你实现相同的功能而不需要任何的CPAN模块:
use v5.15.6; # until v5.16 is released
sub factory {
my $start = shift;
sub {
state $count = $start;
say $count;
return if --$count < 0;
__SUB__->();
}
};
和许多添加于Perl v5.10的新特性一样,你可以像上面的代码示例一样通过使用"use 版本号"这样的语句来开启__SUB__特性,你还可以使用"use feature"导入current_sub来实现同样的功能:
use feature qw(say state current_sub);
sub factory {
my $start = shift;
sub {
state $count = $start;
say $count;
return if --$count < 0;
__SUB__->();
}
};
factory(7)->(); 需要记住的东西: