3

我有以下。

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 没有运行方法,因此它默认为我想要的包 A 运行方法。此时我希望它打印出Package B的名称(会有很多不同的包继承Package A,但它没有。

目前它使用__PACKAGE__变量打印出包 A。

有什么帮助吗?

4

3 回答 3

10

一个对象是一个有福的参考。__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";
}
于 2012-11-02T15:38:58.890 回答
2

用这个替换A::run代码...

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

...将为您提供调用者对象所属的包(类)的名称(因为在对象上调用的每个方法的第一个参数是该对象本身,并将ref其类名作为字符串返回)

于 2012-11-02T15:41:50.910 回答
0

caller()是对此的一般答案,因为它可以为您提供所需的任何堆栈帧,包括包名称。

于 2012-11-02T15:51:00.560 回答