为什么 Perl 允许在不受欢迎的数据结构上调用 coderefs?
执行语句$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
那么为什么它可以与 coderef 一起使用?:
my $process = \&process; # Same method as before
$data->$process( @params ); # Works fine now
When executing the statement $obj->method();
, perldiag
says that Perl needs to know what package the method belongs to. That's why it needs to be blessed:
Can't call method "%s" on unblessed reference
(F) A method call must know in what package it's supposed to run. It
ordinarily finds this out from the object reference you supply, but
you didn't supply an object reference in this case. A reference isn't
an object reference until it has been blessed. Seeperlobj
.
Because of this, it isn't possible to do the following:
my $data = [
[ 1, 2, 3 ],
[ 4, 5, 6 ],
];
$data->process( @params ); # Can't call method "process" on unblessed reference
Then why does it work with a coderef?:
my $process = \&process; # Same method as before
$data->$process( @params ); # Works fine now
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
只是调用
但是 Perl 应该在哪个包中找到
method
子例程?如果$variable
是一个受祝福的引用,Perl将在ref $variable
返回的包中查找子例程。如果 $variable 是一个字符串和一个包的名称,Perl 将在该包名称中查找子例程。在第二个示例中,当您声明
已向 Perl 提供对要调用的代码的引用时,Perl 知道要接受调用
并调用
or
仅当
$variable
是 不受欢迎的引用,并且方法名称无法解析为代码引用,Perl 无法弄清楚要做什么和下注。just invokes
But in which package should Perl find the
method
subroutine? If$variable
is a blessed reference, Perl will look for the subroutine in the package returned byref $variable
. If$variable
is a string and the name of a package, Perl will look for the subroutine in that package name.In your second example, when you declare
you have given Perl the reference to the code you want to invoke, so Perl knows to take the call
and invoke
or
It is only when
$variable
is an unblessed reference, and the method name can not be resolved into a code reference, that Perl cannot figure out what to do and punts.当 perl 看到
$x->$y
时,它会将其编译为如下内容:如果
$y
恰好是一个裸字,则第一个检查始终为 false,然后else
块执行正常的方法调用。When perl sees
$x->$y
it compiles it into something like:If
$y
happens to be a bareword, the first check is always false, and then theelse
block performs a normal method call.在第一个示例中,您尝试按名称调用数组引用的方法;数组引用没有任何方法,所以这根本没有意义。
在第二个示例中,您使用类似的语法,但在本例中
->
只是用于调用右侧参数并将左侧参数作为第一个参数的语法糖;它不是调用实例方法,而是简单地调用一个子例程,其中的参数以令人困惑的方式指定。In the first example, you're trying to call a method of an array reference by name; the array reference doesn't have any methods, so this doesn't even make sense.
In the second example, you're using similar syntax, but in this case the
->
is just syntactic sugar for calling the right-hand parameter with the left-hand parameter as the first argument; it's not calling an instance method, it's simply invoking a subroutine with the parameter specified in a confusing way.