可以通过*var{NAME}
打印变量的名称,是否可以在子程序中打印参数的名称?
下面是我想要达到的效果
var_name($myVar); will print myVar
sub var_name{
print *_{NAME}; # Prints `_`, but want `myVar`
}
首先,您使用print *_{name};
的尝试工作;但是它打印与_
的typeglob相关的名称(用于$_
和@_
之类的东西),这不是您想要的。如果将typeglob/对typeglob的引用传递给函数,则可以通过取消引用参数来提取其名称:
#!/usr/bin/env perl
use warnings;
use strict;
use feature qw/say/;
# The prototype isn't strictly necessary but it makes it harder
# to pass a non-typeglob value.
sub var_name :prototype(*) {
say *{$_[0]}{NAME}; # Note the typeglob deref
}
my $myVar = 1;
say *myVar{NAME}; # myVar
var_name *myVar; # myVar
你得到_
,因为与*_
相关联的NAME
是_
。
那么应该使用什么glob呢?那么,包含用作参数的变量(如果有的话)的glob没有传递给sub,所以您就不走运了。
基于全局的解决方案永远不会与my
变量一起工作,因为这些变量在全局变量中找不到。这意味着基于全局的varname
的概念在实践中不可能起作用。
获取变量的名称需要在调用站点之前检查操作码树。我相信这就是操作符在以下情况下实现这一点的方式:
$ perl -we'my $y; my $x = 0 + $y;'
Use of uninitialized value $y in addition (+) at -e line 1.
$ perl -MO=Concise -we'my $y; my $x = 0 + $y;'
a <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter v ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
3 <0> padsv[$y:1,3] vM/LVINTRO ->4
4 <;> nextstate(main 2 -e:1) v:{ ->5
9 <2> sassign vKS/2 ->a
7 <2> add[t3] sK/2 ->8 <-- This is what's issuing
5 <$> const[IV 0] s ->6 the warning.
6 <0> padsv[$y:1,3] s ->7 <-- This is the source of
8 <0> padsv[$x:2,3] sRM*/LVINTRO ->9 the name in the warning.
-e syntax OK