当方法是 CODEREF 时继承如何工作?

How inheritance works when method is CODEREF?

Mojo::EventEmitter中我们有下一行代码:

for my $cb (@$s) { $self->$cb(@_) }

其中$cb是回调的CODEREF

如果我写:

会有什么不同吗?
for my $cb (@$s) { $cb->($self, @_) }

我想继承不会起作用,因为 $cbCODEREF,因为它在 $cb 包含带有方法名称的字符串的情况下起作用。 所以在这种情况下,重写的代码将以类似的方式工作。

我明白了吗还是漏掉了什么?

$cb是代码引用时,不检查继承。其实$self根本就没考过


$cb为代码引用时,

$self->$cb(@_)

在功能上等同于

$cb->($self, @_)

这就是为什么 $cb 应该使用遵循继承的 can 获得。

package Parent {
   sub new { bless({ @_ }, shift) }
   sub method { CORE::say("!"); }
}

package Child {
   our @ISA = 'Parent';
}

my $self = Child->new();
my $method_name = 'method';

my $cb = $self->can($method_name)
   or die("The object's class doesn't have method $method_name\n");

$self->$cb();

请注意,有些人使用

my $f = "function_name";
undef->$f();

替代

my $f = "sub_name";
no strict qw( refs );
$f->();

然而,用方法调用来调用非方法是很不合适的,而且这个技巧只有在sub没有参数的情况下才有效。如果您真的对 no strict 的这种(适当)使用有疑问,您可以使用以下 (documented) 技巧:

my $f = "sub_name";
(\&$f)->();              # \&$f isn't subject to "use strict qw( refs );" checks