2012-11-02 27 views
2

我有以下几点。Perl中的引用子类包名称

package A; 

sub new { 
    my ($class) = @_; 
    my $self = { }; 
    bless $self, $class; 
    return($self); 
} 

sub run() { 
    die "Task: ",__PACKAGE__, "requires a run method"; 
} 

package B; 
use A; 
our @ISA = qw(A); 
sub new { 
    my ($class) = @_; 
    my $self = { }; 
    bless $self, $class; 
    return($self); 
} 

package C; 
use A; 
my @Tasks; 

sub new { 
    my ($class) = @_; 
    my $self = { }; 
    bless $self, $class; 
    return($self); 
} 

sub add{ 
    my($self,$tempTask) = @_ ; 
    push(@Tasks,$tempTask); 
    $arraysize = @Tasks; 
} 

sub execute{ 
    foreach my $obj (@Tasks) 
    { 
      $obj->run(); 
    } 
} 
1; 

脚本

#!/usr/local/bin/perl 
use strict; 
use C; 
use B; 

my $tb = new C(); 
my $task = new B(); 
$tb->add($task); 
$tb->execute(); 

B套餐没有一个run方法,因此它默认为套餐A run方法这是我想要的。在这一点上,我希望它打印出包B的名称(会有继承A套餐许多不同的包,但它不。

目前,它使用__PACKAGE__变量打印出A套餐。

任何帮助?

回答

9

对象是有福的参考。__PACKAGE__总是等于当前包的名称。但是,ref($object)会给你的类对象的名称,还有Scalar::Util::blessed,它不会给你非误报 - 参考文献

use Scalar::Util qw<blessed>; 

my $obj = bless {}, 'A'; 
my $class = ref({});  # HASH 
$class = blessed({}); # '' 
$class = ref($obj);  # A 
$class = blessed($obj); # A 
你的具体情况

所以:

sub run() { 
    die "Task: " . ref(shift) . "requires a run method"; 
} 
2

更换A::run代码与此...

die "Task: ", ref shift, " requires a run method"; 

...会给你的包(类)的名称,主叫对象所属(作为对象调用的每个方法的第一个参数是该对象本身,而ref将返回它的类名作为字符串)

0

caller()是ge这个答案是最基本的答案,因为它可以给你任何你想要的栈帧,包括包名称。

+0

它会给你''C''在这种情况下,但。 – Axeman

+0

如果您将它用作调用者(EXPR),则EXPR会告诉您要返回多少帧。 –

+0

在调用一个继承方法的一般情况下,你会返回多少堆栈框架来确定调用该方法的子类的名称?不要忘记考虑调用通向基类的情况,因为没有子类覆盖它,以及在一个或多个子类重写该方法并使用SUPER显式调用父实现的情况下。 –