有谁知道如何理解这种Perl代码块?

时间:2014-07-02 08:57:28

标签: perl

我对Perl Named Blocks感到困惑(我认为它们是......)。以下是一个例子:

#!/usr/bin/perl

sub Run(&){
  my ($decl) = @_;
  $decl->();  
}

sub cmd(&){
  my($decl)   = @_;
  my(@params) = $decl->();
  print "@params\n";
}
sub expect(&){
  my ($decl) = @_;  
  my(@params) = $decl->();
  print "@params\n";
}

Run {
  cmd { "echo hello world " };
  expect { exit_code => 0, capture => 2}; 
};

注意最后一行。它看起来像“Run”,“cmd”,“expect”是命名块,但不是函数。有谁知道它们是什么?任何可用的链接介绍它们? 我找不到任何这种语法的参考。

3 个答案:

答案 0 :(得分:9)

让我们解释Run的这个定义:

sub Run(&){
  my ($decl) = @_;
  $decl->();  
}

它表示名为Run的子例程,它接受CODE类型的参数(这就是它使用(&)的原因)。其内部$decl被分配给该传递的代码,此代码由$decl->();调用。

现在,您示例中的最后一行:

Run {
  cmd { "echo hello world " };
  expect { exit_code => 0, capture => 2}; 
};

相当于:

Run(sub {
  cmd { "echo hello world " };
  expect { exit_code => 0, capture => 2}; 
});

换句话说,它使用括号中的匿名过程代码调用Run

答案 1 :(得分:5)

Runcmdexpectprototype定义的函数,它们的工作方式类似于内置函数(无需编写sub{..},这是隐含的(&)这些函数的签名。)

如果这些函数是在没有原型的情况下定义的,那么

sub Run { .. }
sub cmd { .. }
sub expect { .. }

然后显式sub{}参数不是可选的,而是必需的,

Run(sub{
  cmd(sub{ "echo hello world " });
  expect(sub{ exit_code => 0, capture => 2}); 
});

答案 2 :(得分:4)

它们是接受块作为参数的子例程。见:http://perldoc.perl.org/perlsub.html#Prototypes。其定义中的(&)意味着他们的第一个参数是一个代码块。