变量名中的perl变量替换
#!/usr/bin/perl
my $var_a;
$sub_a = "a";
$var_a = "a";
print ${var_."$sub_a"},"\n";
$sub_b = "b";
$var_b = "b";
print ${var_."$sub_b"},"\n";
__DATA__
b
为什么要打印b,但不是?这对我来说似乎是非常意想不到的行为。变量名中的perl变量替换
我正在尝试使用具有替代名称的变量。在实践中,我不能只声明变量,因为赋值是在forloop中完成的,因此具有不同的词汇范围。
请注意,此无关的事实,您使用的变量包含其他变量的名字:如果你想正确地做到这一点你是关闭使用哈希更好。
这不起作用的原因是因为${"var_a"}
构造实际上是指包级变量$main::var_a
。
由于$var_a
被声明为词法变量,因此它是一个不同的标识符,因此${"var_a"}
是undef。
你可以看到,如果你改变my $var_a
到our $var_a
our $var_a="a";
my $var_b="b";
$var_c="c";
print ${"var_a"},"\n";
print ${"var_b"},"\n";
print ${"var_c"},"\n";
######## RESULTS:
a
c
正如其他人所指出的,虽然是为什么你正在尝试做是不行的,你在做什么可能是一个很好的解释错误的方法。除非没有更好的方法,否则几乎不应该使用这种方法;没有你的问题,目前还不清楚更好的方法是什么,但最有可能的是像TLP的回答所说的那样。
谢谢,这回答了技术问题。我并不是真的在寻找解决我的“问题”的方法,而是对行为的解释。 – EricR 2012-08-02 19:26:08
如果您想要符号引用,您希望使用散列。
my %user_vars = (var_a => 'what ever');
my $sub_a = 'a';
print $user_vars{"var_$sub_a"};
Output: 'what ever'
做不使用符号引用用于此目的,因为他们没有必要,也有可能在你的问题的情况下是非常有害的。有关更多信息,请参阅Why it's stupid to 'use a variable as a variable name'?。几乎总是有一个更好的方法来做到这一点,一种方法是使sub_a
和var_a
阵列,其中sub_a
是var_a
的关键。这是很好的做法,当你不使用它们,以防止injection attacks始终锁定您的哈希值,例如:
use strict;
use warnings;
use Hash::Util qw(lock_hash unlock_hash);
my @sub_a;
my %var_a;
lock_hash(%var_a);
@sub_a = qw(a b c); # the keys
unlock_hash(%var_a);
%var_a = (a => 'Value for a', b => 'Value for b', c => 'Value for c');
lock_hash(%var_a);
print $var_a{$sub_a[0]}; # 'Value for a'
print $var_a{'banana'}; # Fatal error when accessing data for banana.
您能否引用锁定哈希来防止注入攻击?干杯。 – EricR 2012-08-02 19:26:43
如果可变哈希值接收到用户输入信息,这是我在大学时被告知的,那么在我的第一份工作中就会引起注入攻击,因此这就是我告诉其他人的信息。总是锁定哈希数组,并且只有在对正在计划添加的变量进行检查之后才解锁它们。我已经添加了关于如何引起注入攻击的参考链接。 – 2012-08-03 00:45:07
抱歉,按键锁定无助于注射攻击。相反,您应该启用污点检查,请参阅[perldoc perlsec](http://p3rl.org/sec)。 – daxim 2012-08-03 00:52:01
使用字符串作为参考违反strict
编译,你应该总是使用。
use strict;
use warnings;
my %hash;
$hash{"var_a"} = "a";
print $hash{"var_a"},"\n";
'为什么会发生这种情况?'定义“这个”?与其询问如何操作“黑客”,您应该询问您的问题以及如何正确执行。使用字符串作为引用违反'strict'编译指示,应该避免。 – TLP 2012-08-02 18:54:41
@TLP,我知道。但是,perl支持变量名称中的变量,我希望利用这个事实。我认为“这个”会很明显。 “a”不打印,而“b”是。我已经调整了问题。我完全有意用哈希来正确地完成它,并从一开始就做好准备。我希望看看能否实施并发现我认为是我不明白的奇怪行为。 – EricR 2012-08-02 19:19:02