gmpassos has asked for the wisdom of the Perl Monks concerning the following question:

There is a way to get the subroutine name, but for a cloned reference?

What I want is to have a subrotine &test1, than make a reference to it at &test2, and when I call test1 or test2 know what name I'm using to call them.

I have tried caller(0), that return some extra values, including the subroutine name, but always the real/first name.

To understand better see this code:

sub test1 { my ($package, $filename, $line, $subroutine, @rest) = caller(0) ; print "<$subroutine> @_\n" ; } *test2 = \&test1 ; &test1(123) ; &test2(456) ;
The output is:
<main::test1> 123 <main::test1> 456
Soo, you can see that calling from &test1 or &test2 $subroutine is always 'main::test1'!

Note that I can't change the behavior or the way that I call &test1 or &test2.

Graciliano M. P.
"Creativity is the expression of the liberty".

Replies are listed 'Best First'.
Re: Getting the name of the subroutine called. There is a way for a clone references?!
by liz (Monsignor) on Sep 08, 2003 at 08:28 UTC
    If you're not interested in performance, but just want to log when which subroutine is called, then you can steal both code references and replace them with a routine of your own. Something like this:
    { # start a scope here to prevent interference with anything else my $test = \&main::test1; # only need this once as they are the same *main::test1 = sub { print "<main::test1> @_\n"; goto &$test }; *main::test2 = sub { print "<main::test2> @_\n"; goto &$test }; } # $test kept because still refs in the anonymous subs

    Hope this helps.

    Liz

Re: Getting the name of the subroutine called. There is a way for a clone references?!
by chromatic (Archbishop) on Sep 08, 2003 at 06:12 UTC

    No, not really, not in a reliable fashion, since exports and references and anonymous subroutines can all get in the way. I suspect there's an easier way to accomplish what you really need, though. What is the problem you're trying to solve?

Re: Getting the name of the subroutine called. There is a way for a clone references?!
by Anonymous Monk on Sep 08, 2003 at 06:38 UTC
    My guess is that caller simply needs improving
    use Devel::Peek; package DO; sub A{warn@_}; *DO=\&A; Devel::Peek::Dump(\%DO::); __END__ SV = RV(0x1c1d05c) at 0x1abf0cc REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x1ab24cc SV = PVHV(0x1aadf70) at 0x1ab24cc REFCNT = 4 FLAGS = (SHAREKEYS) IV = 2 NV = 0 ARRAY = 0x1abb4f0 (0:7, 2:1) hash quality = 75.0% KEYS = 2 FILL = 1 MAX = 7 RITER = -1 EITER = 0x0 NAME = "DO" Elt "DO" HASH = 0x95b SV = PVGV(0x1aaf3bc) at 0x1abf180 REFCNT = 2 FLAGS = (GMG,SMG,MULTI,ASSUMECV,IN_PAD) IV = 0 NV = 0 MAGIC = 0x1ab0c70 MG_VIRTUAL = &PL_vtbl_glob MG_TYPE = '*' MG_OBJ = 0x1abf180 NAME = "DO" NAMELEN = 2 GvSTASH = 0x1ab24cc "DO" GP = 0x1aaf384 SV = 0x1c1d748 REFCNT = 1 IO = 0x0 FORM = 0x0 AV = 0x0 HV = 0x0 CV = 0x1ab252c CVGEN = 0x0 GPFLAGS = 0x0 LINE = 1 FILE = "-e" FLAGS = 0xe EGV = 0x1abf180 "DO" Elt "A" HASH = 0x43 SV = PVGV(0x1abb49c) at 0x1c1d79c REFCNT = 2 FLAGS = (GMG,SMG,MULTI,IN_PAD) IV = 0 NV = 0 MAGIC = 0x1abb444 MG_VIRTUAL = &PL_vtbl_glob MG_TYPE = '*' MG_OBJ = 0x1c1d79c NAME = "A" NAMELEN = 1 GvSTASH = 0x1ab24cc "DO" GP = 0x1abb464 SV = 0x1c1d6f4 REFCNT = 1 IO = 0x0 FORM = 0x0 AV = 0x0 HV = 0x0 CV = 0x1ab252c CVGEN = 0x0 GPFLAGS = 0x0 LINE = 1 FILE = "-e" FLAGS = 0xa EGV = 0x1c1d79c "A"
    You can see the CV is identical (0x1ab252c), but EGV is not (EGV = 0x1abf180 "DO" versus EGV = 0x1c1d79c "A"). Soo, wherever pp_caller gets $subroutine from is the wrong spot.

    PS - I am not a perl5-porter, so these are guesses.

Re: Getting the name of the subroutine called. There is a way for a clone references?!
by leriksen (Curate) on Sep 08, 2003 at 07:09 UTC
    I cant see anything in the caller return list to differentiate the subs ... and my first knee-jerk of a class that overloads the '()' operator wont work because in Perl you cant overload '()' (anyone know why C++ supports this and Perl doesn't ??)... perhaps search other references for FUNCTORS, function objects, whose only public method is the () operator. C++ has many examples, see STL. CPAN gives me hits for some modules on a Prolog's emulation - but that is (probably) not going to help.