(sub {
print 1;
})();
sub {
print 1;
}();
Run Code Online (Sandbox Code Playgroud)
我试过各种各样的方法,都错了......
zel*_*lio 38
(sub { ... }) 将为您提供指向该函数的指针,因此您必须通过引用调用.
(sub { print "Hello world\n" })->();
Blagovest Buyukliev指出的另一个简单方法是取消引用函数指针并使用{ }运算符调用它
&{ sub { print "Hello World" }}();
Egg*_*ung 26
是的,我没想到你们会想出那么多的可能性.但你是对的,这是perl和TIMTOWTDI:为creativitiy +1!
但说实话,我使用的形式几乎不是以下形式:
my $greet = sub {
my ( $name ) = @_;
print "Hello $name\n";
};
# ...
$greet->( 'asker' )
Run Code Online (Sandbox Code Playgroud)
它非常简单:sub {}返回对子例程的引用,您可以像任何其他标量一样存储和传递子例程.您可以通过解除引用来调用它.还有第二种解除引用的语法:&{ $sub }( 'asker' )但我个人更喜欢箭头语法,因为我发现它更具可读性,并且几乎与解除引用哈希$hash->{ $key }和数组一致$array->[ $index ].有关参考文献的更多信息可以在perldoc perlref中找到.
我认为其他给出的例子有点高级,但为什么不看看它们:
sub bar {goto $foo};
bar;
Run Code Online (Sandbox Code Playgroud)
这些天很少见,也很害怕.但至少它是一个goto &function,被认为比它的歪歪扭扭的朋友更有害:goto LABEL或者goto EXPRESSION(自5.12起就被弃用并发出警告).实际上有些情况下,当你想使用那个表格时,因为这不是通常的函数调用.调用函数(bar在给定的示例中)不会出现在调用堆栈中.并且您没有传递参数,但@_会使用当前的参数.看看这个:
use Carp qw( cluck );
my $cluck = sub {
my ( $message ) = @_;
cluck $message . "\n";
};
sub invisible {
@_ = ( 'fake' );
goto $cluck;
}
invisible( 'real' );
Run Code Online (Sandbox Code Playgroud)
输出:
fake at bar.pl line 5
main::__ANON__('fake') called at bar.pl line 14
Run Code Online (Sandbox Code Playgroud)
堆栈跟踪中没有隐藏功能的提示.关于goto in perldoc -f goto的更多信息.
''->$foo;
# or
undef->$foo;
Run Code Online (Sandbox Code Playgroud)
如果在对象上调用方法,则传递给该方法的第一个参数将是调用者(通常是实例或类名).我已经说过TIMTOWTCallAFunction了吗?
# this is just a normal named sub
sub ask {
my ( $name, $question ) = @_;
print "$question, $name?\n";
};
my $ask = \&ask; # lets take a reference to that sub
my $question = "What's up";
'asker'->ask( $question ); # 1: doesn't work
my $meth_name = 'ask';
'asker'->$meth_name( $question ); # 2: doesn't work either
'asker'->$ask( $question ); # 1: this works
Run Code Online (Sandbox Code Playgroud)
在上面的代码片段中有两个调用,这些调用无效,因为perl将尝试查找ask在包中调用的方法asker(实际上,如果该代码位于所述包中,它将起作用).但第三个成功,因为你已经给perl正确的方法,它不需要搜索它.一如既往:perldoc中的更多信息我现在找不到任何理由,请原谅生产代码.
最初我并不打算写那么多,但我认为在答案的开头有一个共同的解决方案,并对不寻常的结构有一些解释是很重要的.我承认在这里有点自私:我们每个人都可能最终维护某些代码,他们发现了这个问题并且只是复制了最顶层的例子.
Eri*_*rom 12
在Perl中没有太多需要调用定义它的匿名子例程.通常,您可以使用裸块实现任何类型的范围.想到的一个用例是创建一个别名数组:
my $alias = sub {\@_}->(my ($x, $y, $z));
$x = $z = 0;
$y = 1;
print "@$alias"; # '0 1 0'
Run Code Online (Sandbox Code Playgroud)
否则,您通常会在变量或数据结构中存储匿名子例程.以下调用样式适用于变量和sub {...}声明:
dereference arrow: sub {...}->(args) or $code->(args)
dereference sigil: &{sub {...}}(args) or &$code(args)
Run Code Online (Sandbox Code Playgroud)
如果你在标量中有coderef,你也可以将它用作常规和祝福值的方法.
my $method = sub {...};
$obj->$method # same as $method->($obj)
$obj->$method(...) # $method->($obj, ...)
[1, 2, 3]->$method # $method->([1, 2, 3])
[1, 2, 3]->$method(...) # $method->([1, 2, 3], ...)
Run Code Online (Sandbox Code Playgroud)
通过寻找调用匿名函数的方法,我无休止地被逗乐:
$foo = sub {say 1};
sub bar {goto $foo};
bar;
''->$foo; # technically a method, along with the lovely:
undef->$foo;
() = sort $foo 1,1; # if you have only two arguments
Run Code Online (Sandbox Code Playgroud)
当然,显而易见的是:
&$foo();
$foo->();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18148 次 |
| 最近记录: |