Reputation: 456
I have a situation where I need to find the caller of a package and my code looks something like:
Inherited.pm:
package Inherited;
our @ISA = qw(BaseClass);
sub new {
SUPER::new();
}
BaseClass.pm
package BaseClass;
sub new {
$a = caller(0);
print $a
}
Now I have another class (MyClass.pm) which does:
MyClass.pm:
$obj = Inherited->new();
This prints Inherited. But I need MyClass to be the printed statement.
Could someone please help me out on how to solve this ??
Upvotes: 5
Views: 1409
Reputation: 132730
When you give caller an argument, you tell it how many levels to go back. You've given it the argument 0
, which is the current level. If you want one level up, add 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;
}
Now the result is:
0: Inherited
1: MyClass
Remember to always include complete example programs in your questions. The Perl code you posted was broken for various other reasons unrelated to caller.
Upvotes: 5
Reputation: 118595
If I'm reading your post correctly, you need to find the last frame in the call stack that is calling a constructor.
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;
}
or
package BaseClass;
sub new {
my @a;
unshift @a, [ caller(@a) ] while caller(@a);
my ($a) = grep { $_->[4] =~ /::new$/ } @a;
print $a // caller(0);
}
The second code snippet will handle the case when there are intermediate function calls that are not constructors, e.g., if the call stack looks like
GrandChild::new
GrandChild::init
Inherited::new
BaseClass::new
the first snippet would return the caller for Inherited::new
(which presumably would be GrandChild
, and the second one would return the caller of GrandChild::new
.
Upvotes: 1