Zai*_*aid 8 methods perl coderef
执行语句时$obj->method();,perldiag说Perl需要知道方法属于哪个包.这就是为什么它需要得到祝福:
无法在未完成的引用上调用方法"%s"
(F)方法调用必须知道它应该运行在哪个包中.它通常从您提供的对象引用中找到它,但在这种情况下您没有提供对象引用.在被祝福之前,引用不是对象引用.见
perlobj.
因此,不可能执行以下操作:
my $data = [
[ 1, 2, 3 ],
[ 4, 5, 6 ],
];
$data->process( @params ); # Can't call method "process" on unblessed reference
Run Code Online (Sandbox Code Playgroud)
那为什么它与coderef一起工作?:
my $process = \&process; # Same method as before
$data->$process( @params ); # Works fine now
Run Code Online (Sandbox Code Playgroud)
mob*_*mob 22
$variable->method(@args)
Run Code Online (Sandbox Code Playgroud)
只是调用
method($variable, @args)
Run Code Online (Sandbox Code Playgroud)
但Perl在哪个包中找到method子程序?如果$variable是一个有福的引用,Perl将在返回的包中查找子例程ref $variable.如果$variable是字符串和包的名称,Perl将在该包名中查找子例程.
在您的第二个示例中,当您声明时
$process = \&process
Run Code Online (Sandbox Code Playgroud)
您已经为Perl提供了要调用的代码的引用,因此Perl知道接听电话
$variable->$process(@args)
Run Code Online (Sandbox Code Playgroud)
并调用
$process->($variable, @args)
Run Code Online (Sandbox Code Playgroud)
要么
&process($variable, @args)
Run Code Online (Sandbox Code Playgroud)
只有当$variable是unblessed参考和方法名称不能被解析成一个代码参考,而Perl想不出做什么和平底船.
Eri*_*rom 10
当perl看到$x->$y它将它编译成类似于:
if (reftype $y eq 'CODE') {
$y->($x)
}
else {
if (my $code_ref = eval {$x->can($y)}) {
$code_ref->($x)
}
else {
die "error"
}
}
Run Code Online (Sandbox Code Playgroud)
如果$y恰好是一个单词,则第一次检查始终为false,然后该else块执行常规方法调用.
在第一个示例中,您尝试按名称调用数组引用的方法; 数组引用没有任何方法,所以这甚至没有意义.
在第二个例子中,你使用了类似的语法,但在这种情况下,->只是用于调用右手参数的语法糖,左手参数作为第一个参数; 它不是调用实例方法,它只是调用一个子程序,其参数以令人困惑的方式指定.