当方法是 CODEREF 时继承如何工作?
How inheritance works when method is CODEREF?
在Mojo::EventEmitter中我们有下一行代码:
for my $cb (@$s) { $self->$cb(@_) }
其中$cb
是回调的CODEREF
。
如果我写:
会有什么不同吗?
for my $cb (@$s) { $cb->($self, @_) }
我想继承不会起作用,因为 $cb
是 CODEREF
,因为它在 $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
在Mojo::EventEmitter中我们有下一行代码:
for my $cb (@$s) { $self->$cb(@_) }
其中$cb
是回调的CODEREF
。
如果我写:
会有什么不同吗?for my $cb (@$s) { $cb->($self, @_) }
我想继承不会起作用,因为 $cb
是 CODEREF
,因为它在 $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