你能在Perl中打印子例程的参数名称吗?



可以通过*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

最新更新