#!/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中完成的,因此具有不同的词法范围。
答案 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_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.
答案 2 :(得分:0)
使用字符串作为引用会违反strict
pragma,您应该始终使用它。如果你想正确地使用哈希,最好使用哈希:
use strict;
use warnings;
my %hash;
$hash{"var_a"} = "a";
print $hash{"var_a"},"\n";