Кто-нибудь знает, как понимать такие блоки кода Perl?

#perl

#perl

Вопрос:

Меня смущают именованные блоки Perl (я думал, что они …). Ниже приведен пример:

 #!/usr/bin/perl

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

sub cmd(amp;){
  my($decl)   = @_;
  my(@params) = $decl->();
  print "@paramsn";
}
sub expect(amp;){
  my ($decl) = @_;  
  my(@params) = $decl->();
  print "@paramsn";
}

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

Обратите внимание на последние строки. Похоже, что «Run», «cmd», «expect» — это именованные блоки, но не функции. Кто-нибудь знает, что это такое? Любая доступная ссылка представляет их?
Я не могу найти ни одной ссылки на такую грамматику.

Ответ №1:

Давайте расшифруем это определение для Run :

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

Это означает вызываемую подпрограмму Run , которая принимает параметр типа CODE (вот почему он использует (amp;) ). Внутри него $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. Спасибо за ваш любезный ответ. Это то, что я хотел.

Ответ №2:

Run cmd , и expect являются prototype определенными функциями, и они работают как встроенные функции (не нужно писать sub{..} , так как это неявно из-за (amp;) подписи для этих функций).

Если бы эти функции были определены без прототипов,

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

тогда явные sub{} аргументы были бы не необязательными, а обязательными,

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

Ответ №3:

Это подпрограммы, принимающие блок в качестве аргумента. Смотрите: http://perldoc.perl.org/perlsub.html#Prototypes. (amp;) В их определениях означает, что их первым аргументом является блок кода.