为什么我不能使用 Perl 变量的值来访问词法变量名称?
为什么这会打印 42:
$answer = 42;
$variable = "answer";
print ${$variable} . "\n";
而这却不会:
my $answer = 42;
my $variable = "answer";
print ${$variable} . "\n";
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
只有包变量(在第一个示例中声明的类型)可以通过符号引用作为目标。词法(
my
)变量不能是,这就是你的第二个示例失败的原因。请参阅优秀文章应对作用域,了解 Perl 中两个独立变量系统的运作方式。请参阅同样出色的为什么使用变量变量名称是愚蠢的,了解为什么这是愚蠢的。 :)
Only package variables (the kind declared in your first example) can be targeted via symbolic references. Lexical (
my
) variables, cannot be, which is why your second example fails.See the excellent article Coping with Scoping for how the two separate variable systems in Perl operate. And see the also excellent Why it's stupid to use a variable variable name for why that's stupid. :)
Perl 有两个完全独立但很大程度上兼容的变量系统,包变量(如第一个示例中所示)和词法变量(如第二个示例中所示)。有一些事情每个都可以做,但另一个不能:
包变量是唯一可以:
local
)词法变量是唯一可以关闭的变量(在词法闭包中使用)。
使用 strict 会强制您使用
our
声明包变量,从而使差异更加清晰。在 Perl 中,符号引用有很多时候很有用,大多数集中在操作符号表上(比如在模块中编写自己的
import
而不是使用Exporter
、monkey-patching运行时的模块,各种其他元编程任务)。所有这些都是高级主题。对于其他任务,通常有更好的方法来完成,例如使用哈希。一般经验法则是始终在使用警告下运行; use strict; 除非您知道除了禁用一部分编译指示之外没有其他方法(例如在尽可能小的范围内使用
no strict 'refs';
) 。Perl has two entirely separate but largely compatible variable systems, package variables, as in your first example, and lexical variables, as in the second. There are a few things that each can do but the other cant:
Package variables are the only ones that can be:
local
)Lexical variables are the only ones that can be closed over (used in a lexical closure).
Using strict would help by forcing you to declare package variables with
our
, making the difference clearer.There are several times where symbolic references are useful in Perl, most center around manipulating the symbol table (like writing your own
import
in a module rather than usingExporter
, monkey-patching modules at runtime, various other meta-programming tasks). All of these are advanced topics.For other tasks, there is usually a better way to do it such as with a hash. The general rule of thumb is to always run under
use warnings; use strict;
unless you know there isn't any other way but to disable a portion of the pragma (such as usingno strict 'refs';
in as small a scope as possible).符号引用仅适用于包变量。符号表不跟踪词法变量(这就是它们作为词法的全部意义:)。
Symbolic references only work with package variables. The symbol table doesn't track lexical variables (which is the entire point of them being lexical :).
问题是您不能使用符号引用来引用词法变量。在这两个示例中,
${$variable}
都在查找$main::answer
。在第一个中,$answer
是一个全局包,是$main::answer
的缩写,因此引用可以找到它。在第二个中,$answer
是一个词法变量,并不存在于任何包中,因此引用无法找到它。更多详细信息,请参见标题 perlref perlref.html#Symbolic-references" rel="noreferrer">符号引用。
The problem is that you can't use a symbolic reference to refer to a lexical variable. In both examples
${$variable}
is looking for$main::answer
. In the first,$answer
is a package global and short for$main::answer
, so the reference finds it. In the second,$answer
is a lexical variable and doesn't live in any package, so the reference can't find it.More details in perlref under heading Symbolic references.