Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Anyone Know How to Understand Such Kind of Perl Code Blocks?

Tags:

perl

I'm confused by Perl Named Blocks (I thought they are...). Below is an example:

#!/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}; 
};

Note the last lines. It looks like "Run", "cmd", "expect" are named blocks, but not functions. Does anyone know what they are? Any available link introduces them? I can't find any reference for such grammar.

like image 648
Hao Avatar asked Jul 02 '14 08:07

Hao


2 Answers

Let's decipher this definition for Run:

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

It means subroutine called Run, which accepts parameter of type CODE (that's why it uses (&)). Inside it $decl gets assigned to that passed code, and this code gets called by $decl->();.

Now, last lines in your example:

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

are equivalent to:

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

In other words, it calls Run with anonymous procedure code that is in braces.

like image 190
mvp Avatar answered Sep 27 '22 19:09

mvp


Run, cmd, and expect are prototype defined functions, and they work like built-in functions (no need to write sub{..}, as this is implicit due (&) signature for these functions).

If these functions were defined without prototypes,

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

then explicit sub{} arguments would be not optional but required,

Run(sub{
  cmd(sub{ "echo hello world " });
  expect(sub{ exit_code => 0, capture => 2}); 
});
like image 23
mpapec Avatar answered Sep 27 '22 19:09

mpapec