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 ??
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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With