我是函数式编程的忠实粉丝,所以当我在Perl中发现块引用时,我开始大量使用它们.
但是,我编写的以块为参数的函数是用这种样式编写的:
sub mygrep (&@) {
my $code = shift;
my @result;
foreach $_ (@_) {
push(@result, $_) if &$code;
}
@result;
}
Run Code Online (Sandbox Code Playgroud)
(来自http://perldoc.perl.org/perlsub.html#Prototypes)
本质上,我的大部分功能$_都是为了让代码块能够访问我的sub中的数据而设置的.我想我的问题可以分为三个子问题:
localIZE $_设置之前?我仍然是一个Perl新手所以任何答案和建议都表示赞赏 - 提前感谢!:)
在您编写的代码中:
sub mygrep (&@) {
my $code = shift;
my @result;
foreach $_ (@_) {
push(@result, $_) if &$code;
}
@result;
}
Run Code Online (Sandbox Code Playgroud)
该foreach循环是隐含在本地化$_上的每个循环迭代变量.它是完全安全的(并且是获得$_正确值的最快方法).
我对上面代码的唯一要点是,每次&$code执行时,它都可以访问源参数列表,这可能会导致错误.您可以按如下方式重写代码:
sub mygrep (&@) {
my $code = shift;
my @result;
foreach $_ (splice @_) {
push(@result, $_) if &$code; # @_ is empty here
}
@result;
}
Run Code Online (Sandbox Code Playgroud)
以下是您可以编写该功能的其他几种方法:
sub mygrep (&@) {
my ($code, @result) = shift;
&$code and push @result, $_ for splice @_;
@result
}
sub mygrep (&@) {
my $code = shift;
# or using grep in our new grep:
grep &$code, splice @_
}
Run Code Online (Sandbox Code Playgroud)
这些示例中的每一个$_都为其子例程提供了别名,并具有适当的本地化.
如果您对高阶函数感兴趣,我建议您查看我的模块List :: Gen on CPAN,它提供了许多高阶函数来操作实数和惰性列表.
use List::Gen;
my $list = filter {$_ % 2} <1..>;
# as a lazy array:
say "@$list[0 .. 5]"; # 1 3 5 7 9 11
# as an object:
$list->map('**2')->drop(100)->say(5); # 40401 41209 42025 42849 43681
zip('.' => <a..>, <1..>)->say(5); # a1 b2 c3 d4 e5
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
239 次 |
| 最近记录: |