变量名中的perl变量替换

时间:2012-08-02 18:45:43

标签: 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,但不是?这对我来说似乎是非常意想不到的行为。

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

3 个答案:

答案 0 :(得分:7)

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

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

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

如果您将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的回答所说的那样。

答案 1 :(得分:3)

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

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_avar_a数组,其中sub_avar_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.

答案 2 :(得分:0)

使用字符串作为引用会违反strict pragma,您应该始终使用它。如果你想正确地使用哈希,最好使用哈希:

use strict;
use warnings;

my %hash;

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