我正在撰寫一個封裝父類的多個物件的子類,這樣我就可以呼叫函式,有點像向量,如下所示:
package OriginalClass;
sub new { return bless {bar => 123}, 'OriginalClass' }
sub foo { return shift->{bar}; }
1;
package NewClass;
use parent OriginalClass;
# Return a blessed arrayref of "OriginalClass" objects.
# new() would be called NewClass->new(OriginalClass->new(), ...)
sub new {
my $class = shift;
return bless \@_, 'NewClass';
}
# Vectorized foo(), returns a list of SUPER::foo() results:
sub foo
{
my $self = shift;
my @ret;
push @ret, $_->SUPER::foo() foreach @$self;
return @ret;
}
1;
我不想為 中NewClass的每個函式撰寫一個新的向量化函式OriginalClass,尤其是當在中OriginalClass添加要維護(向量化)的新函式時NewClass。
問題:
據我了解AUTOLOAD很慢,所以有沒有辦法OriginalClass通過類似NewClasswithout的方式對呼叫進行矢量化AUTOLOAD?
uj5u.com熱心網友回復:
據我了解
AUTOLOAD很慢
如果AUTOLOAD生成缺少的子程式,那么只有第一次呼叫是“慢”的,因為相同方法的后續呼叫根本不會導致AUTOLOAD被呼叫。
package NewClass;
use strict;
use warnings;
sub new {
my $class = shift;
return bless( \@_, $class );
}
sub AUTOLOAD {
my $method_name = our $AUTOLOAD =~ s/^.*:://sr;
my $method = sub {
my $self = shift;
return map { $_->$method_name( @_ ) } @$self;
};
{
no strict 'refs';
*$method_name = $method;
}
goto &$method;
}
1
請注意,我沒有使用parentand SUPER::。這不是繼承關系。并且它將防止AUTOLOAD被呼叫,因為AUTOLOAD僅在方法不存在時才呼叫。
您可以使用 Sub::Name 來“命名子”以獲得更好的診斷。
use Sub::Name qw( subname );
my $method = subname $method_name => sub { ... };
不過是的,AUTOLOAD這里可以避免,只要能提前拿到方法名的串列。
package NewClass;
use strict;
use warnings;
sub new {
my $class = shift;
return bless( \@_, $class );
}
for my $method_name (qw( foo ... )) {
my $method = sub {
my $self = shift;
return map { $_->$method_name( @_ ) } @$self;
};
no strict 'refs';
*$method_name = $method;
}
1
以上使用硬編碼串列,但更多動態解決方案是可能的。例如,可以通過檢查 OriginalClass 命名空間的內容來獲取串列(過濾掉new以及其他不合適的內容,例如以 開頭的名稱_)。
uj5u.com熱心網友回復:
模塊https://metacpan.org/pod/Array::Delegate可能會有所幫助:它將方法呼叫委托給物件陣列。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/524268.html
標籤:perl模块矢量化子类
上一篇:Mojolicious奇怪的餅干
下一篇:在perl中使用變數呼叫sed
