为什么我要使用Perl匿名子例程而不是命名子例程? [英] Why would I use Perl anonymous subroutines instead of a named one?

查看:97
本文介绍了为什么我要使用Perl匿名子例程而不是命名子例程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很好奇为什么在Perl中为什么会选择使用匿名子例程而不是命名子例程.谢谢.

I'm just curious why one would choose to use an anonymous subroutine, versus a named one, in Perl. Thanks.

推荐答案

  • 您可以将匿名子存储在数组,哈希和标量中.
  • 您可以在运行时构建它们
  • 您可以将它们作为参数传递给其他函数.
  • 您可以将变量保留在范围内.
  • 最后一点可能是最重要的,因为它通常是Perl中命名子程序与匿名子程序最不可思议的方面.示例:

    The last point is probably the most important, because it's often the most unexpected facet of named vs. anonymous subroutines in Perl. Example:

    sub outer
    {
      my $a = 123;
    
      sub inner
      {
        print $a, "\n";
      }
    
      # At this point, $a is 123, so this call should always print 123, right?
      inner();
    
      $a = 456;
    }
    
    outer(); # prints 123
    outer(); # prints 456! Surprise!
    

    但是将内部"从命名子例程更改为对匿名子例程的引用,它的工作方式就不那么令人惊讶了:

    But change "inner" from a named subroutine to a reference to an anonymous subroutine and it works is a much less surprising manner:

    sub outer
    {
      my $a = 123;
    
      my $inner = sub
      {
        print $a, "\n";
      };
    
      # At this point, $a is 123, and since the anonymous subrotine 
      # whose reference is stored in $inner closes over $a in the 
      # "expected" way...
      $inner->();
    
      $a = 456;
    }
    
    # ...we see the "expected" results
    outer(); # prints 123
    outer(); # prints 123
    

    (当然,每个人的期望都不同,因此期望"周围的恐吓报价".)

    (Of course, everyone's expectations are different, thus the "scare quotes" around "expected.")

    这是真实代码中的一个示例用法(尽管应注意,File::Find接口由于使用全局变量而不是使用匿名子例程而通常被认为是较差的一个):

    Here's an example use in real code (though it should be noted that the File::Find interface is generally considered to be a poor one—due to its use of global variables, not its use of anonymous subroutines):

    sub find_files
    {
      my @files;
    
      my $wanted = sub
      { 
        if($something)
        {
          push @files, $File::Find::name;
        }
      };
    
      # The find() function called here is imported from File::Find
      find({ wanted => $wanted }, $directory);
    
      return @files;
    }
    

    将命名子例程作为wanted参数的值传递将需要使用只能使用一次的例程来污染名称空间,并在find_files()子例程内定义命名子例程 .表现出前面演示的意外"行为.

    Passing a named subroutine as the value of the wanted parameter would require polluting the namespace with a routine that may only be used once, and defining a named subroutine within the find_files() subroutine would exhibit the "unexpected" behavior demonstrated earlier.

    这篇关于为什么我要使用Perl匿名子例程而不是命名子例程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆