vlee
vlee

Reputation: 1407

Determining the subroutine name of a Perl code reference

How would one determine the subroutine name of a Perl code reference? I would also like to distinguish between named and anonymous subroutines.

Thanks to this question I know how to print out the code, but I still don't know how to get the name.

For example, I'd like to get 'inigo_montoya' from the following:

#!/usr/bin/env perl

use strict;
use warnings;

use Data::Dumper;
$Data::Dumper::Deparse = 1;

my $sub_ref = \&inigo_montoya;

print Dumper $sub_ref;



# === subroutines ===

sub inigo_montoya {
  print <<end_quote;
I will go up to the six-fingered man and say, "Hello. My name is Inigo
Montoya. You killed my father. Prepare to die."';
end_quote
}

Upvotes: 24

Views: 5466

Answers (4)

Egga Hartung
Egga Hartung

Reputation: 1091

Why not ask, what the compiler sees? (It would return __ANON__ on anonymous subs).

#!/usr/bin/perl

use strict;
use warnings;

my $sub_ref = \&inigo_montoya;


use B qw(svref_2object);
my $cv = svref_2object ( $sub_ref );
my $gv = $cv->GV;
print "name: " . $gv->NAME . "\n";


sub inigo_montoya {
    print "...\n";
}

Upvotes: 28

Kaoru
Kaoru

Reputation: 1570

Sub::Identify does exactly this, hiding all that nasty B::svref_2object() stuff from you so you don't have to think about it.

#!/usr/bin/env perl

use strict;
use warnings;
use feature 'say';

use Sub::Identify ':all';

my $sub_ref = \&inigo_montoya;

say "Sub Name: ",   sub_name($sub_ref);
say "Stash Name: ", stash_name($sub_ref);
say "Full Name: ",  sub_fullname($sub_ref);

# === subroutines ===

sub inigo_montoya {
    print <<'    end_quote';
I will go up to the six-fingered man and say, "Hello. My name is Inigo
Montoya. You killed my father. Prepare to die."';
    end_quote
}

Which outputs:

$ ./sub_identify.pl 
Sub Name: inigo_montoya
Stash Name: main
Full Name: main::inigo_montoya

Upvotes: 12

Axeman
Axeman

Reputation: 29854

Expanding on Jan Hartung's idea (and scrapping my own), you could get a fully qualified name and some trace information for no matter what it is or where it came from:

use B qw(svref_2object);

sub sub_name {
    return unless ref( my $r = shift );
    return unless my $cv = svref_2object( $r );
    return unless $cv->isa( 'B::CV' )
              and my $gv = $cv->GV
              ;
    my $name = '';
    if ( my $st = $gv->STASH ) { 
        $name = $st->NAME . '::';
    }
    my $n = $gv->NAME;
    if ( $n ) { 
        $name .= $n;
        if ( $n eq '__ANON__' ) { 
            $name .= ' defined at ' . $gv->FILE . ':' . $gv->LINE;
        }
    }
    return $name;
}

Upvotes: 8

user554546
user554546

Reputation:

I'm not sure about calling the name of the function from the outside, but you can get it from within the subroutine via the caller function:

sub Foo {print "foo!\n";return (caller(0))[3];}
$function_name=Foo();
print "Called $function_name\n";

This has the following output:

foo!
Called main::Foo

Of course, you can return the function name as one of the items that the subroutine returns. That way, you can capture it and have the option of displaying it (or using it in other logic, etc).

Upvotes: 4

Related Questions