如何将函数传递给Perl子?

use*_*033 2 perl function

我怎么写一个接受像map函数那样的函数呢?

例:

$func = sub { print $_[0], "hi\n" };
&something($f);
sub something
{
    my $func = shift;
    for ($i = 0; $i < 5; $i++)
    {    $func->($i);    }
}
Run Code Online (Sandbox Code Playgroud)

工作良好.

但是如果我这样做的话

&something( { print $_[0], "hi\n" } );
Run Code Online (Sandbox Code Playgroud)

它不会工作,并说func是一个未定义的引用.

所以我的问题是如何编写一个接受perls map函数等参数的函数?

map { s/a/b/g } @somelist;
Run Code Online (Sandbox Code Playgroud)

Eev*_*vee 17

map函数具有非常神奇的语法,除非你有充分的理由,否则你可能不想复制它.只需使用常规的匿名子,如下所示:

something(sub { print $_[0], "hi\n" });
Run Code Online (Sandbox Code Playgroud)

但是,如果你真的想这样做,你需要使用原型:

sub my_map (&@) {
    my ($func, @values) = @_;
    my @ret;
    for (@values) {
        push @ret, $func->($_);
    }
    return @ret;
}

my @values = my_map { $_ + 1 } qw(1 2 3 4);
print "@values";  # 2 3 4 5
Run Code Online (Sandbox Code Playgroud)

(注意,它$_是动态范围的,因此它在调用程序中的任何值都保留在函数中.)

List::Util并且List::MoreUtils做了很多这样的事情来创建看起来内置的函数并且像map/的变体一样grep.这是唯一一个应该使用这种东西的情况.


Sin*_*nür 6

首先,&在调用subs 时不要使用.来自perldoc perlsub:

子程序可以递归调用.如果使用& 表单调用子例程,则参数列表是可选的,如果省略,则不@_ 为子例程设置@_ 数组:调用时的数组对子例程可见.这是新用户可能希望避免的效率机制.

如果您希望能够将普通块传递给" sub something",则需要使用原型,如下所示:

sub something(&@);

# later

sub something(&@) {
    my ($coderef, @args) = @_;

}
Run Code Online (Sandbox Code Playgroud)

请参阅原型.

我个人只会传递一个明确的subref:

something( sub { } );
Run Code Online (Sandbox Code Playgroud)