2010-04-01 2 views
25

В Perl мы можем получить имя текущего пакета и текущего номера строки. Используя предопределенные переменные, такие как __PACKAGE__ и __LINE__.Как я могу получить имя текущей подпрограммы в Perl?

Как это я хочу, чтобы получить имя текущей подпрограммы:

use strict; 
use warnings; 

print __PACKAGE__; 
sub test() 
{ 
    print __LINE__; 
} 
&test(); 

В приведенном выше коде я хочу, чтобы получить имя подпрограммы внутри функции test.

+1

Какой выход вы хотите, если текущая подпрограмма является анонимным? –

+5

'sub test() {}' определяет функцию с прототипом «()». Я предполагаю, что вы хотели 'sub test {}' –

+0

Кроме того, не помещайте амперсанд ('&') перед вызовом подпрограммы, потому что он, вероятно, не делает того, что, по вашему мнению, он делает. – mpeters

ответ

16

caller - это правильный способ сделать это в @eugene pointed out, если вы хотите сделать это внутри подпрограммы.

Если вы хотите, чтобы другая часть вашей программы могла идентифицировать информацию об упаковке и названии для coderef, используйте Sub::Identify.

Кстати, глядя на

sub test() 
{ 
    print __LINE__; 
} 
&test(); 

Есть несколько важных моментов, говоря: Во-первых, не используйте prototypes, если вы пытаетесь имитировать встроенные команды. Во-вторых, не используйте &, если invoking a subroutine, если только вам не нужны необходимые эффекты.

Поэтому, что сниппет лучше записать в виде:

sub test 
{ 
    print __LINE__; 
} 
test(); 
49

Используйте caller() функцию:

my $sub_name = (caller(0))[3];

Это даст вам имя текущей подпрограммы, в том числе его пакета (например 'main::test'). Закрытие возвращает имена, такие как 'main::__ANON__', а в eval будет '(eval)'.

+3

, который дает вам основную :: __ ANON__ для анонимного sub (или foo :: __ ANON__, если анонимная поднаболка определена в пакете 'foo ') – mirod

+7

@mirod: 'local * __ ANON__ =" foo ";' - это может использоваться для установки имени для анонимных подпрограмм. –

+0

приятно! (не то, что я сделал бы это, конечно ...) – mirod

0

Там специальный __SUB__ существует с perl-5.16.

use v5.16; 
use Sub::Identify qw/sub_fullname/; 
sub foo { 
    print sub_fullname(__SUB__); # main::foo 
} 

foo(); 

На самом деле вы можете перейти к sub_fullname любую ссылку на подпрограмму (даже анонимное):

use Sub::Identify qw/sub_fullname/; 
sub foo { 
    print sub_fullname(\&foo); # main::foo 
    print sub_fullname(sub{}); # main::__ANON__ 
} 

foo(); 
+0

И если кто-то хочет дать имя '__ANON__', см. [здесь] (http://www.perlmonks.org/?node_id = 395912) –

Смежные вопросы