perl - 探索匿名订阅者的使用

标签 perl

我一直对 perl 中匿名 subs 的目的和用法有些困惑。我理解这个概念,但正在寻找有关此实践值(value)的示例和解释。

要清楚:

sub foo { ... }   # <--- named sub
sub { ... }       # <--- anonymous sub

例如:
$ perl -e 'print sub { 1 }'
CODE(0xa4ab6c)

告诉我 sub 返回一个标量值。所以,我可以这样做:
$ perl -e '$a = sub { 1 }; print $a'

对于与上面相同的输出。这当然适用于所有标量值,因此您可以使用匿名子项加载数组或散列。

问题是,我如何使用这些潜艇?我为什么要使用它们?

而对于金星来说,有没有什么问题只能通过匿名潜艇来解决?

最佳答案

匿名子程序可用于各种事情。

  • 事件处理系统的回调:
    my $obj = Some::Obj->new;
    
    $obj->on_event(sub {...});
    
  • 迭代器:
    sub stream {my $args = \@_; sub {shift @$args}}
    
    my $s = stream 1, 2, 3;
    
    say $s->(); # 1
    say $s->(); # 2 
    
  • 高阶函数:
    sub apply (&@) {
        my $code = shift;
        $code->() for my @ret = @_;
        @ret
    }
    
    my @clean = apply {s/\W+/_/g} 'some string', 'another string.';
    
    say $clean[0]; #  'some_string'
    
  • 创建别名数组:
    my $alias = sub {\@_}->(my $x, my $y);
    
    $alias[0]++;
    $alias[1] = 5;
    
    say "$x $y";  # '1 5''
    
  • 使用闭包进行动态编程(例如创建一堆只有少量差异的子程序):
    for my $name (qw(list of names)) {
        no strict 'refs';
        *$name = sub {... something_with($name) ...};
    }
    

  • 在任何情况下,匿名子例程都可以做命名子例程不能做的任何事情。 my $ref = sub {...}构造函数等效于以下内容:
    sub throw_away_name {...}
    
    my $ref = \&throw_away_name;
    

    不必费心为每个 sub 决定一个唯一的“throw_away_name”。

    等价也有相反的情况,即 sub name {...}相当于:
     BEGIN {*name = sub {...}}
    

    因此,除了名称之外,任何一种方法创建的代码引用都是相同的。

    要调用子例程引用,您可以使用以下任何一种:
     $code->();         # calls with no args
     $code->(1, 2, 3);  # calls with args (1, 2, 3)
     &$code();          # calls with no args
     &$code;            # calls with whatever @_ currently is
    

    您甚至可以使用代码引用作为受祝福或不受祝福的标量的方法:
     my $list = sub {@{ $_[0] }};
    
     say for [1 .. 10]->$list  # which prints 1 .. 10 
    

    关于perl - 探索匿名订阅者的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6535894/

    相关文章:

    linux - 是否有任何 Perl 模块来替换旧的镜像模块?

    regex - 从文本文件中的重复范围模式中获取特定行

    PERL 5.8.4 安装 DBI 模块

    perl - 如何在 Perl 中通过 SIGHUP 在 while(1) 之后跳转?

    arrays - 为什么这个函数显示的是一个数组的数组而不是一个数组?

    perl - 如何在 DBIx::Class 中获取表的类名

    perl - Perl子例程末尾的()是什么意思?

    perl - 在什么情况下 "unless"与 "if not"不同?

    perl - 目前进行并行下载最舒适和可靠的跨平台 Perl 模块是什么?

    perl - 带有警报消息的 scp 命令