为什么我不能使用Perl变量的值来访问词法变量名?

时间:2010-02-25 23:15:12

标签: perl variables metaprogramming lexical

为什么打印42:

$answer = 42;
$variable = "answer";

print ${$variable} . "\n";

但这不是:

my $answer = 42;
my $variable = "answer";

print ${$variable} . "\n";

4 个答案:

答案 0 :(得分:15)

只能通过符号引用来定位包变量(在第一个示例中声明的类型)。词法(my)变量不可能,这就是你的第二个例子失败的原因。

有关Perl中两个独立变量系统的运行方式,请参阅优秀文章Coping with Scoping。并且看到这也是非常好的Why it's stupid to use a variable variable name为什么那是愚蠢的。 :)

答案 1 :(得分:6)

Perl有两个完全独立但基本兼容的变量系统,包变量(如第一个示例中)和词法变量(如第二个)。除了另一个之外,每个人都可以做一些事情:

包变量是唯一可以的:

  1. 本地化(使用local
  2. 用作符号引用的目标(OP的第二个例子不起作用的原因)
  3. 用作裸字(子定义,文件句柄)
  4. 与typeglobs一起使用(因为这就是符号真正在引擎盖下)
  5. 词汇变量是唯一可以被关闭的变量(用于词法闭包)。

    使用strict会强制您使用our声明包变量,从而使差异更加清晰。

    有几次符号引用在Perl中很有用,大多数都围绕着操作符号表(比如在模块中编写自己的import而不是使用Exporter,在运行时使用猴子修补模块,各种其他元编程任务)。所有这些都是高级主题。

    对于其他任务,通常有更好的方法,例如使用哈希。一般的经验法则是始终在use warnings; use strict;下运行,除非您知道没有任何其他方法可以禁用部分编译指示(例如在尽可能小的范围内使用no strict 'refs';

答案 2 :(得分:5)

符号引用仅适用于包变量。符号表不跟踪词汇变量(这是词汇的整个点:)。

答案 3 :(得分:4)

问题是你不能使用符号引用来引用词法变量。在这两个示例中,${$variable}正在寻找$main::answer。在第一个中,$answer是一个全局包,$main::answer的缩写,因此引用找到它。在第二个中,$answer是一个词法变量,并不存在于任何包中,因此引用无法找到它。

perlref标题Symbolic references下的更多详细信息。