如何在perl中将invocant的名称作为字符串

时间:2016-04-30 19:09:37

标签: perl perl-module

在perl中,类“Lamba”实现了一个名为“process”的方法。

use Lambda;
my $omega = Lambda->new();
$omega->process();

在流程方法中,我们怎样才能得到它的名字?#/ p>

package Lambda;
use strict;

sub new {
    my $class = shift;
    my $self = {};
    bless ($self, $class);
    return $self; 
} 

sub process {
    my $self = shift;
    my $invocant;
    #
    # ??? what is the variable name of my caller ???
    #
    # ie. how to set $invocant = 'omega';
    #
    return $self;
} 

2 个答案:

答案 0 :(得分:4)

更新

我刚刚意识到您需要用于调用process方法的变量的名称。如果没有源过滤器,您就无法做到这一点,因为可能有多个名称都指向同一个对象,例如

my $omega = Lambda->new;
my $aa    = $omega;
my $bb    = $omega;

$aa->process;

并且非常明智地无法掌握用于调用方法的名称​​

这是X Y problem,与询问如何使用数据字符串命名变量相当。变量标识符纯粹是供程序员使用,如果您认为您的程序需要了解它们,那么您就会遇到设计问题。如果您通过这种机制确切地解释了想要实现的目标,那么我相信我们可以帮助您更好地


原始解决方案

我已经把这个留在了这里,有人来到这个页面寻找一种方法来发现呼叫代码的名称

您可以使用caller功能

没有caller()等参数的呼叫将返回当前呼叫所在的包名,源文件名和行号

通过添加一个表示要检查的调用堆栈深度的参数,可以获得更详细的信息,因此caller(0)将返回有关当前子例程的信息,而来自caller(1)的值将与调用子例程

有关

如果我们改变你的主代码使用子程序来调用方法,那么我们可以写这个

Lambda.pm

package Lambda;

use strict;
use warnings;

sub new {
    bless {}, shift;
} 

sub process {
    my $self = shift;

    #
    # ??? what is the variable name of my caller ???
    #
    # ie. how to set $invocant = 'omega';
    #
    my $calling_sub = (caller(1))[3];
    print "Called by $calling_sub\n";

    return $self;
} 

1;

main.pl

use strict;
use warnings 'all';

use Lambda;

mysub();

sub mysub {
    my $omega = Lambda->new;
    $omega->process;
}

输出

Called by main::mysub

答案 1 :(得分:1)

caller function返回有关调用子例程/源代码行的信息:

sub process {
    my $self = shift;

    print join(', ',caller(0)); # Some of these values will be undef!
}

manual page显示了这个例子:

($package, $filename, $line, $subroutine, $hasargs,
$wantarray, $evaltext, $is_require, $hints, $bitmask, $hinthash)
 = caller($i);

增加$i以进一步浏览堆栈跟踪(反向调用者列表):

my $i = 0;
while (my @ci = caller($i++)) {
    print "$i. ".$ci[1].':'.$ci[2]."\n";
}

$i=0开始,并在将其传递给$i函数后增加caller() 。将堆栈跟踪打印回脚本行,开始当前进程。