如何将函数传递给Perl子?
我该如何编写一个接受类似map函数的函数呢?如何将函数传递给Perl子?
例子:
$func = sub { print $_[0], "hi\n" };
&something($f);
sub something
{
my $func = shift;
for ($i = 0; $i < 5; $i++)
{ $func->($i); }
}
工作正常。
但当时如果我没有
&something({ print $_[0], "hi\n" });
它不会工作,并说FUNC是一个未定义的参考。
所以我的问题是我将如何编写一个函数,接受参数像perls map函数?
map { s/a/b/g } @somelist;
的map
功能具有非常神奇的语法,你可能不希望除非你有一个很好的理由将它复制;只是使用普通的无名子,是这样的:
something(sub { print $_[0], "hi\n" });
如果你真的想这样做,不过,你需要使用prototype:
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
(注意:$_
动态范围的,所以任何值已在来电者的功能被保留。)
List::Util
和List::MoreUtils
做这样的事情很多创建外观内置功能和行为像的变种10/grep
。这真的是唯一的情况下应该使用这样的东西。
&something({ print $_[0], "hi\n" });
# ^^^ this isn't a reference
&something(sub { print $_[0], "hi\n" }); # works just fine
为什么你有'&'放在前面? – 2009-08-21 16:58:28
大概是因为OP有一个,答案是复制OP的风格。即使前缀可能不应该在那里,正如SinanÜnür解释的那样。 – 2009-08-21 17:22:37
首先,在拨打sub
s时不要使用&
。从perldoc perlsub
:
子程序可以递归调用。如果使用
&
表单调用子例程,则参数列表是可选的,如果省略,则不会为该子例程设置@_
数组:调用时该数组的@_
对子例程可见。这是新用户可能希望避免的效率机制。
如果你希望能够通过一个简单的块“sub something
”,您需要使用的原型为:
sub something(&@);
# later
sub something(&@) {
my ($coderef, @args) = @_;
}
我个人只想传递一个明确的子参考:
something(sub { });
+1。我喜欢用“for”语句对$ _进行本地化的想法 - 允许1-arg funcrefs变得简洁明了。 (我想你可以“本地($ a,$ b);”对于2-arg funcrefs la sort()。) – 2009-08-22 18:06:59