2016-09-30 70 views
2

Mojo::EventEmitter我們的下一行代碼:當方法是CODEREF時繼承是如何工作的?

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

哪裏$cb是回調的CODEREF

請問有什麼不同,哪些是如果我寫:

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

我想是因爲$cb:繼承是行不通的是CODEREF因爲它在情況下$cb包含字符串的方法名。 所以在這種情況下,重寫代碼的工作原理類似。

我理解好還是錯過了什麼?

+2

存在丟失的箭頭操作符' - >''$ cb'後。它應該是'$ cb - >($ self,@_)' –

+0

@HåkonHægland正確的 - 如果'$ cb'確實是一個coderef,那麼在源代碼中我就不清楚了。 – zdim

+0

@zdim OP說它是'CODEREF'。所以我信任他。 –

回答

5

$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->(); 

然而,這是相當不恰當的使用方法調用來調用非法,而這個技巧只有在子沒有參數時纔有效。如果你真的有這個(適當的)使用的no strict一個問題,您可以在以下的(documented)絕招:

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

但'$ cb'是字符串還是CODEREF? –

+1

當'$ cb'是一個字符串時,將使用繼承 – ikegami

+0

您可以爲'$ self :: $ cb()'場景添加說明嗎? –