Reputation: 428
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.
Upvotes: 6
Views: 241
Reputation: 50637
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});
});
Upvotes: 5
Reputation: 2053
They are subroutines accepting block as an argument. See: http://perldoc.perl.org/perlsub.html#Prototypes. The (&)
in their definitions means that their first argument is a block of code.
Upvotes: 4
Reputation: 116108
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.
Upvotes: 9