开发者

How do I pass an anonymous subroutines when calling a Perl subroutine?

my开发者_如何学编程sub gets a subroutine reference as its first argument.

Can I simply call mysub(sub{some subroutine body here}) ? I.e. define an anonymous subroutine right at the call?

Is the syntax OK (is it really a reference to sub that is passed)?


What happened when you tried it? That's surely the best way to test whether things like this work.

But, yes, that syntax will work just fine.

#!/usr/bin/perl

use strict;
use warnings;

sub run_sub {
  shift->();
}

run_sub( sub { print "hello\n"; } );


Since passing subroutine references to other subroutines is a fairly common pattern, Perl even has a few syntax tricks to make it even smoother:

sub function1 {          # normal declaration, implicit `(@)` prototype
    my $code = shift;
    $code->(@_);
}

sub function2 (&@) {     # prototyped declaration
    my $code = shift;
    $code->(@_);
}

function1 has to be called as: function1 sub{...}, any_other_args

function2 has the prototype (&@) which tells the compiler to impose subroutine context on the first argument (and then accept any number of additional arguments).

So you can call it as function2 {...} any_other_args which mirrors the way the higher order builtins like map, grep, and sort take their code blocks. Note that there is no comma after the code block, just like with the bultins.

You can find more information about prototypes here: http://perldoc.perl.org/perlsub.html#Prototypes

Keep in mind that Perl's prototypes are NOT for argument validation, they are hints to the compiler that allow you to write subroutines that behave like builtins.


Alternatively (to the answer by @davorg), you can use:

sub run_sub
{
    my($funcref) = @_;
    &$funcref();
}

More verbose, certainly; also a little clearer, I think. But this is Perl - TMTOWTDI!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜