5

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

继承.pm:

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

基类.pm

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

现在我有另一个类(MyClass.pm):
MyClass.pm:

$obj = Inherited->new();  

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

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

4

2 回答 2

5

当你给调用者一个参数时,你告诉它要返回多少级。你已经给了它参数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无关的各种其他原因而被破坏。

于 2012-04-04T17:05:33.253 回答
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.

于 2012-04-04T15:15:06.260 回答