gpt4 book ai didi

Perl - 向 subs 发送 block 时的最佳实践

转载 作者:行者123 更新时间:2023-12-04 22:00:15 24 4
gpt4 key购买 nike

我是函数式编程的忠实粉丝,所以当我在 Perl 中发现 block 引用时,我开始大量使用它们。

但是,我编写的将 block 作为参数的函数是用这种风格编写的:

sub mygrep (&@) {
my $code = shift;
my @result;
foreach $_ (@_) {
push(@result, $_) if &$code;
}
@result;
}

(来自 http://perldoc.perl.org/perlsub.html#Prototypes)

本质上,我的大部分功能都设置了 $_为了让代码块能够访问我的 sub 中的数据。我想我的问题可以分为三个子问题:
  • 这种方法是否存在一些重大缺陷?
  • local 是更好的主意吗?放大 $_在设置之前?
  • 我应该改用部分应用的函数吗?

  • 我仍然是 Perl 新手,因此感谢您提供任何答案和建议 - 在此先感谢! :)

    最佳答案

    在您编写的代码中:

    sub mygrep (&@) {
    my $code = shift;
    my @result;
    foreach $_ (@_) {
    push(@result, $_) if &$code;
    }
    @result;
    }
    foreach循环隐式本地化 $_每次循环迭代的变量。它是完全安全的(也是将值正确输入 $_ 的最快方法)。

    我对上面代码的唯一缺点是每次 &$code执行时,它可以访问源参数列表,这可能会导致错误。你可以重写代码如下:
    sub mygrep (&@) {
    my $code = shift;
    my @result;
    foreach $_ (splice @_) {
    push(@result, $_) if &$code; # @_ is empty here
    }
    @result;
    }

    以下是您可以编写该函数的其他几种方法:
    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 @_
    }

    这些示例中的每一个都提供了一个别名 $_到它的子程序,并具有适当的本地化。

    如果你对高阶函数感兴趣,我建议你看看我的模块 List::Gen在 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

    关于Perl - 向 subs 发送 block 时的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7740496/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com