我有一种情况需要找到包的调用者,我的代码看起来像:
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 作为印刷语句。
有人可以帮我解决一下这个问题吗?
答案 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
的调用者。