变量名中的perl变量替换

变量名中的perl变量替换,perl,Perl,为什么打印的是b而不是a?这对我来说似乎是非常意外的行为 我试图使用一个替换名称的变量。实际上,我不能不声明变量,因为赋值是在forloop中完成的,因此具有不同的词法范围。如果需要符号引用,则需要使用哈希 #!/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"; __

为什么打印的是b而不是a?这对我来说似乎是非常意外的行为


我试图使用一个替换名称的变量。实际上,我不能不声明变量,因为赋值是在forloop中完成的,因此具有不同的词法范围。

如果需要符号引用,则需要使用哈希

#!/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
不要为此目的使用符号引用,因为它们是不必要的,并且在你的问题中可能非常有害。有关详细信息,请参阅。几乎总是有更好的方法来做到这一点,一种方法是制作
sub\u a
var\u a
数组,其中
sub\u a
var\u a
的关键。在不使用哈希时,最好始终锁定哈希,以防止出现以下情况,例如:

my %user_vars = (var_a => 'what ever');
my $sub_a = 'a';
print $user_vars{"var_$sub_a"};


Output: 'what ever'

使用字符串作为引用违反了应始终使用的
strict
pragma。如果您想正确地使用散列,最好使用散列:

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.

请注意,这与使用变量来包含其他变量的名称无关

这不起作用的原因是
${“var_a”}
构造实际上指的是包级变量
$main::var_a

由于
$var_a
被声明为一个词法变量,它是一个不同的标识符,因此
${“var_a”}
是未定义的

如果将
my$var\u a
更改为
our$var\u a

use strict;
use warnings;

my %hash;

$hash{"var_a"} = "a";
print $hash{"var_a"},"\n";

正如其他人所指出的,虽然有一个很好的解释可以解释为什么你试图做的不起作用,但你所做的很可能是错误的方法。除非没有更好的方法,否则你几乎不应该使用这种方法;如果没有您的问题,现在还不清楚更好的方法是什么,但很可能是像TLP的答案所说的那样的散列。

为什么会发生这种情况?
定义“这个”?与其问如何操作“黑客”,你应该问你的问题以及如何正确操作。使用字符串作为引用违反了
strict
pragma,应该避免使用。@TLP,我知道。然而,perl确实支持变量名中的变量,我希望利用这一事实。我认为“这”是显而易见的。不打印“a”,而打印“b”。我已经调整了这个问题。我完全想用散列正确地完成它,并且从一开始就有。我想看看我是否能够实现并发现我认为是奇怪的行为,但我不理解。我想我现在提出这个问题已经太迟了,但作为继续,我想使用类似于{array_type.'$I.'$s'}的东西@{array_type.“$i”}这可以很好地工作,但另一个不行。谢谢,这回答了技术问题。我并不是真的在寻找我的“问题”的解决方案,而是对这种行为的一种解释。你能举出哈希锁来防止注入攻击吗?干杯。如果变量hash曾经收到用户输入,这是我在大学里第一份工作时被告知的,因此这是我告诉其他人的,那么可能会引发注入攻击。始终锁定散列数组,并且仅在对计划添加到散列数组中的变量进行检查后才将其解锁。我已经添加了一个链接,指向如何导致注入攻击的参考。抱歉,密钥锁定对注入攻击没有帮助。相反,您应该启用污染检查,请参阅。很高兴知道,谢谢daxim。我将在下一个项目中研究如何实现这一点。散列锁过时了吗?
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