如何确定Perl代码引用的子例程名称?我还想区分命名子程序和匿名子程序。
感谢this question我知道如何打印代码,但我仍然不知道如何获取名称。
例如,我想从以下内容中获取'inigo_montoya':
#!/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
}
答案 0 :(得分:21)
为什么不问,编译器看到了什么? (它会在匿名潜艇上返回__ANON__
。
#!/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";
}
答案 1 :(得分:8)
Sub::Identify正是如此,隐藏了所有令人讨厌的B::svref_2object()
内容,因此您无需考虑它。
#!/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
}
哪个输出:
$ ./sub_identify.pl
Sub Name: inigo_montoya
Stash Name: main
Full Name: main::inigo_montoya
答案 2 :(得分:7)
扩展Jan Hartung的想法(并自行删除),您可以获得完全限定的名称和一些跟踪信息,无论它是什么或来自何处:
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;
}
答案 3 :(得分:4)
我不确定从外部调用函数的名称,但您可以通过caller
函数从子例程中获取它:
sub Foo {print "foo!\n";return (caller(0))[3];}
$function_name=Foo();
print "Called $function_name\n";
这有以下输出:
foo!
Called main::Foo
当然,您可以将函数名称作为子例程返回的项之一返回。这样,您可以捕获它并可以选择显示它(或在其他逻辑中使用它等)。