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

Eug*_*kov 2 perl mojolicious

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

for my $cb (@$s) { $self->$cb(@_) }
Run Code Online (Sandbox Code Playgroud)

哪里$cbCODEREF回调的.

如果我写的话会有什么不同吗?

for my $cb (@$s) { $cb->($self, @_) }
Run Code Online (Sandbox Code Playgroud)

我想,继承不会起作用,因为的$cbCODEREF因为它在情况下,当$cb包含字符串的方法名.因此,在这种情况下,重写代码将起作用.

我理解正确还是错过了什么?

ike*_*ami 5

何时$cb是代码引用,不检查继承.事实上,$self根本没有检查.


什么时候$cb是代码参考,

$self->$cb(@_)
Run Code Online (Sandbox Code Playgroud)

在功能上是相同的

$cb->($self, @_)
Run Code Online (Sandbox Code Playgroud)

这就是为什么$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();
Run Code Online (Sandbox Code Playgroud)

请注意,有些人使用

my $f = "function_name";
undef->$f();
Run Code Online (Sandbox Code Playgroud)

作为替代

my $f = "sub_name";
no strict qw( refs );
$f->();
Run Code Online (Sandbox Code Playgroud)

然而,使用方法调用来调用非方法是非常不合适的,并且这个技巧仅在sub没有参数时才有效.如果您对此(适当)使用确实有问题no strict,您可以使用以下(记录)技巧:

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