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

Guys, here are some codes that I am learning, it demonstrates the caller function in subroutines, the first one works fine, the other code at the bottom does not, in it I am using the sytnax of caller EXPR and it is supposed to be returning back to me the name of the subroutine that called the subroutine which has the caller function in it. (i.e. it would return calling\n main,directory.pl,main::calling,the line# of the "calling"subroutine )...any clues on such unresponsiveness causes and what to do to avoid it?
#works fine sub addem{ ($value1, $value2)=@_; $value1+$value2; print join(':',caller); ($package, $filename, $line)=caller; } $value=addem(2,2); print "\n$value1 + $value2 = $value"; print "\nthe package = $package\n"; print "the file = $filename\n"; print "the line = $line\n";
#not returning anything. sub calling{ $value=addem(2,2); } sub addem{ ($value1, $value2)=@_; $value1+$value2; print join(",", caller 1); }
p.s I am writing this code off a book that I am learning Perl from, it gives concise examples though it is sharp to the point and assumes you have some Perl's background.

Replies are listed 'Best First'.
Re: getting a subroutine's name
by shmem (Chancellor) on Jul 17, 2009 at 17:48 UTC

    It doesn't return anything, because nothing has been called. Only defined.

    Try

    calling();

    That said...

    #works fine sub addem{ ($value1, $value2)=@_; $value1+$value2; print join(':',caller); ($package, $filename, $line)=caller; }

    ...will return 3 for any values you add. You are adding the two values passed and throw away the result. Then you return a list of three items (the last value evaluated in that subrouttine) - $package, $filename, $line - which in scalar context results in the number of elements in that list: 3.

    Works fine? Not.

      this code would work fine even if that caller assignment in list context is commmented out since caller works in list and scalar context as well. in the second code however, the problem arises since I am putting a subroutine call inside a subroutine of its own, and the same exact code is here in the book and the return value is supposed be so I am wondering if there is something different
      the-calling-subroutine-name main, directory/program.pl,line,main::the-calling-subroutine-name
      #works fine sub addem{ ($value1, $value2)=@_; $value1+$value2; print join(':',caller); # ($package, $filename, $line)=caller; }
      even this code works fine if I am not calling from within a subroutine the addem() function,
      #notice disablement of the blocks in the callingfun() makes it work sub addem{ ($value1,$value2)=@_; $value1+$value2; print join(',',caller); } #sub callingfun{ $result = addem(2,2); # }
      so I don't really understand the behavior, tried getting a diagnosis using eval function but did not work out..........
      Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind
        this code would work fine even if that caller assignment in list context is commmented out since caller works in list and scalar context as well.

        Yes, it "works", but it does not return what is expected - the sum of the values passed in.

        in the second code however, the problem arises since I am putting a subroutine call inside a subroutine of its own, and the same exact code is here in the book and the return value is supposed be so I am wondering if there is something different

        caller works fine in subroutine chains, but the subroutines must be called, which you don't do in your "second code."

        Try the following:

        sub calling { $value = addem(2,2); } sub addem { ($value1, $value2) = @_; print join(",", caller 0); $value1+$value2; } # this is the missing piece to make the above output something. # call the subroutine! calling();
Re: getting a subroutine's name
by repellent (Priest) on Jul 17, 2009 at 18:49 UTC
    # obtain CODEref info sub coderef_info { my ($coderef) = @_; return () unless UNIVERSAL::isa($coderef, "CODE"); require B; require B::Deparse; my $cv = B::svref_2object($coderef); my $gv = $cv->GV; return $gv->STASH->NAME, $gv->NAME, $gv->FILE, $cv->START->line, B::Deparse->new->coderef2text($coderef); } use Data::Dumper; print Dumper(coderef_info(\&addem));

    Example output (comments added):
    $VAR1 = 'main'; # package name $VAR2 = 'addem'; # subroutine name $VAR3 = 'coderef.pl'; # filename $VAR4 = 2; # line number where sub was defined $VAR5 = '{ # subroutine code as string ($value1, $value2) = @_; $value1 + $value2; print join(\':\', caller); ($package, $filename, $line) = caller; }';
Re: getting a subroutine's name
by Marshall (Canon) on Jul 17, 2009 at 20:09 UTC
    I have used these simple subs many times to great effect. I put them in a "standard utility module" that I use in many programs. I recommend just setting these short subs to return a string, don't use values in main calling program to separate things out. Perhaps these things should/could be called iwascalledby() hewascalledby(); or whatever suits your fancy.
    #!usr/bin/perl -w use strict; sub whoami { (caller(1))[3] }; sub whowasi { (caller(2))[3] }; some_sub(); sub some_sub { print "Now inside some_sub\n"; print " called_by ". whoami.".\n"; another_sub(); } sub another_sub { print "Now inside another_sub\n"; print " called by ". whoami(). " \n"; print " previous sub ". whowasi(). " \n"; } __END__ Prints: Now inside some_sub called_by main::some_sub. Now inside another_sub called by main::another_sub previous sub main::some_sub
    caller() has more params and they can be useful, eg. line number etc. But basically if one of my library routines gets bogus input, then I usually just need to know the name of the caller and the name of previous caller to figure out where bogus input came from.