7
#!/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,而不是a?这对我来说似乎是非常意外的行为。

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

4

3 回答 3

9

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

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

由于$var_a被声明为词法变量,因此它是一个不同的标识符,因此${"var_a"}是 undef。

您可以看到,如果您更改my $var_aour $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 的答案所说的哈希。

于 2012-08-02T19:00:26.483 回答
4

如果你想要一个符号引用,你想使用一个哈希。

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


Output: 'what ever'

不要为此目的使用符号引用,因为它们在您的问题的上下文中是不必要的并且可能非常有害有关更多信息,请参阅为什么“使用变量作为变量名”很愚蠢?. 几乎总是有更好的方法来做到这一点,一种方法是制作sub_avar_a数组,其中sub_a. var_a最好在不使用散列时始终锁定散列以防止注入攻击,例如:

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.
于 2012-08-02T18:56:18.210 回答
0

使用字符串作为引用违反了strict您应该始终使用的编译指示。如果您想正确执行,最好使用哈希:

use strict;
use warnings;

my %hash;

$hash{"var_a"} = "a";
print $hash{"var_a"},"\n";
于 2012-08-02T18:57:49.517 回答