Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

getting subroutine names

by linuxfan (Beadle)
on Jan 13, 2005 at 01:37 UTC ( [id://421838]=perlquestion: print w/replies, xml ) Need Help??

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

Hello Monks,

I have an array with 20 subrefs. I go through each element of the arrray and execute the subroutine. Sometimes, I have to remove a few subrefs from the array and run my program. As a result, I find it hard to trace the name of the subroutine currently running. My code looks like:

my @tests = (\&test1,\&test2,\&test3,&test4); # 20 odd refs here my $test = 1; foreach my $subref (@tests) { print STDERR "Test # $test++\n"; foreach my $size (1..1000) { $subref->($arg1,$arg2,$size); } }
As you can see, each time I change the elements of the array, the test # printed on STDERR is different from the subroutine that is actually running.

Is there a way I can obtain the name of the subroutine currently running? (like test1, test2 etc.).

Thanks!

Replies are listed 'Best First'.
•Re: getting subroutine names
by merlyn (Sage) on Jan 13, 2005 at 01:44 UTC
    Just provide labels:
    my @tests = ( [one => \&test1], [two => \&test2], ... [twenty => \&test20], ); for my $label_code_pair (@tests) { my ($label, $code) = @$label_code_pair; print STDERR "running $label\n"; $code->(...); }

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      This is exactly what I was looking for :) Thank you very much Randal !
Re: getting subroutine names
by xdg (Monsignor) on Jan 13, 2005 at 02:21 UTC

    I agree with Merlyn that just giving names is the easiest way, by far. However, if you really want to get into some deep, dark perl voodoo, check this out:

    #!/usr/bin/perl use warnings; use strict; sub test1 {1}; sub test2 {2}; sub test3 {3}; sub test4 {4}; sub findsym { no strict 'refs'; my ($pkg,$ref) = @_; foreach my $sym ( values %{$pkg."::"} ) { return *$sym{NAME} if *{$sym}{CODE} && *{$sym}{CODE} == $ref; } } my @tests = (\&test1,\&test2,\&test3,\&test4); foreach my $subref (@tests) { my $name = findsym(__PACKAGE__,$subref); print STDERR "Test $name\n"; print $subref->() . "\n"; }

    I recently discovered this kind of thing poking around in the guts of Attribute::Property and Attribute::Handlers and thought it was pretty cool. I've never even seen a print reference to the {NAME} property of a typeglob.

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

      This solution is even better. Gets me the name of the subroutine!!

      Thanks a lot :)

Re: getting subroutine names
by broquaint (Abbot) on Jan 13, 2005 at 03:26 UTC
    If you don't mind using a bit of black magic and have a relatively recent version of perl (5.7+ perhaps?) then you could use this code
    use B 'svref_2object'; sub name_from_coderef { return svref_2object($_[0])->GV->NAME; } my @tests = (\&test1,\&test2,\&test3,\&test4); # 20 odd refs here my $test = 1; foreach my $subref (@tests) { warn sprintf "Test # %s\n", name_from_coderef($subref); foreach my $size (1..1000) { $subref->($arg1,$arg2,$size); } }
    HTH

    _________
    broquaint

Re: getting subroutine names
by gopalr (Priest) on Jan 13, 2005 at 02:08 UTC

    Hi,

    Use the Caller function, we can determine the name of the currently running function.

    caller

    Regards,

    Gopal.R

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://421838]
Approved by davido
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (5)
As of 2024-03-19 11:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found