Perl继承 - 谁是父类的调用者

时间:2012-04-04 13:30:49

标签: perl perl-module

我有一种情况需要找到包的调用者,我的代码看起来像:

Inherited.pm:

package Inherited;
our @ISA = qw(BaseClass);
sub new {
   SUPER::new();
}

BaseClass.pm

package BaseClass;
sub new {
  $a = caller(0);
  print $a
}

现在我有另一个类(MyClass.pm),它执行:
MyClass.pm:

$obj = Inherited->new();  

这打印继承。但我需要 MyClass 作为印刷语句。

有人可以帮我解决一下这个问题吗?

2 个答案:

答案 0 :(得分:5)

当您给caller一个参数时,您可以告诉它要返回多少级别。你给它的参数0,这是当前的水平。如果您想要提升一级,请添加1

use v5.12;

package Inherited {
    our @ISA = qw(BaseClass);
    sub new {
       $_[0]->SUPER::new();
    }
}

package BaseClass {
    sub new {
      say "0: ", scalar caller(0);
      say "1: ", scalar caller(1);
    }
}

package MyClass {
    my $obj = Inherited->new;
    }

现在的结果是:

0: Inherited
1: MyClass

请记住,在您的问题中始终包含完整的示例程序。您发布的Perl代码因与caller无关的各种其他原因而被破坏。

答案 1 :(得分:1)

如果我正确地阅读你的帖子,你需要在调用堆栈中找到调用构造函数的最后一帧。

package BaseClass;
sub new {
    my $a = caller(0);
    for (my $n=0; my @c=caller($n); $n++) {
        last if $c[4] !~ /::new$/;
        $a = $c[0];
    }
    print $a;
}

package BaseClass;
sub new {
    my @a;
    unshift @a, [ caller(@a) ] while caller(@a);
    my ($a) = grep { $_->[4] =~ /::new$/ } @a;
    print $a // caller(0);
}

当存在不是构造函数的中间函数调用时,第二个代码片段将处理这种情况,例如,如果调用堆栈看起来像

 GrandChild::new
 GrandChild::init
 Inherited::new
 BaseClass::new

第一个代码段将返回Inherited::new的调用者(可能是GrandChild,第二个会返回GrandChild::new的调用者。