如何在perl中将invocant的名称作为字符串获取
how to get the name of invocant as string in perl
在 perl 中,class "Lamba" 实现了一个名为 "process" 的方法。
use Lambda;
my $omega = Lambda->new();
$omega->process();
在process方法中,如何获取调用者的名字?
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;
}
caller
functionreturns关于调用subroutine/sourcecode线路的信息:
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
开始,在 传递给 caller()
函数后增加 $i
。将堆栈跟踪打印回启动当前进程的脚本行。
更新
我刚刚意识到您需要用于调用 process
方法的变量的 name。如果没有源过滤器,您将无法做到这一点,因为可能有多个名称都引用同一个对象,就像这样
my $omega = Lambda->new;
my $aa = $omega;
my $bb = $omega;
$aa->process;
而且很明智地没有办法获得名称 实际上 用于调用方法
这是一个X Y problem,相当于问如何用数据串来命名一个变量。变量标识符纯粹供程序员使用,如果您认为您的程序需要知道它们,那么您就有设计问题了。如果你能准确解释你想通过这个机制实现什么,那么我相信我们可以更好地帮助你
原解
我把这个留在这里,以防有人来到这个页面寻找一种方法来发现调用代码的名称
您可以使用caller
函数
不带参数的调用如 caller()
将 return 包名、源文件名和当前调用所在的行号
您可以通过添加表示要检查的调用堆栈深度的参数来获得更详细的信息,因此 caller(0)
将 return 有关 当前的信息 子程序,而 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
在 perl 中,class "Lamba" 实现了一个名为 "process" 的方法。
use Lambda;
my $omega = Lambda->new();
$omega->process();
在process方法中,如何获取调用者的名字?
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;
}
caller
functionreturns关于调用subroutine/sourcecode线路的信息:
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
开始,在 传递给 caller()
函数后增加 $i
。将堆栈跟踪打印回启动当前进程的脚本行。
更新
我刚刚意识到您需要用于调用 process
方法的变量的 name。如果没有源过滤器,您将无法做到这一点,因为可能有多个名称都引用同一个对象,就像这样
my $omega = Lambda->new;
my $aa = $omega;
my $bb = $omega;
$aa->process;
而且很明智地没有办法获得名称 实际上 用于调用方法
这是一个X Y problem,相当于问如何用数据串来命名一个变量。变量标识符纯粹供程序员使用,如果您认为您的程序需要知道它们,那么您就有设计问题了。如果你能准确解释你想通过这个机制实现什么,那么我相信我们可以更好地帮助你
原解
我把这个留在这里,以防有人来到这个页面寻找一种方法来发现调用代码的名称
您可以使用caller
函数
不带参数的调用如 caller()
将 return 包名、源文件名和当前调用所在的行号
您可以通过添加表示要检查的调用堆栈深度的参数来获得更详细的信息,因此 caller(0)
将 return 有关 当前的信息 子程序,而 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