Perl variable substitution in a variable name

#!/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 

Why is b printed but not? This seems like a very unexpected behavior.

I am trying to use a variable with a substituted name. In practice, I cannot simply not declare a variable, because the assignment is done in forloop and, therefore, has a different lexical scope.

+4
source share
3 answers

Note that this has NOTHING to do with the fact that you use variables to contain the name of another variable.

The reason this doesn't work is because the ${"var_a"} construct actually refers to the package level variable $main::var_a .

Since $var_a declared as a lexical variable, it is a DIFFERENT identifier, and therefore ${"var_a"} is undef.

You can see that if you change my $var_a to 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 

As others have noted, although there is a good explanation of why what you are trying to do does not work, what you are doing is most likely the wrong approach. You will almost never use this method unless there is a better way; without your problem, it’s not clear what the best way is, but most likely there will be a hash, as TLP says.

+7
source

If you need a symlink, you want to use a hash.

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

Do not use symbolic links for this purpose, because they are unnecessary and probably very harmful in the context of your question. For more information, see Why is it silly to "use a variable as a variable name"? . There is almost always a better way to do this, one way is to create arrays of sub_a and var_a , where sub_a is the key for var_a . It’s good practice to always block your hashes when you are not using them to prevent injection attacks , for example:

 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(abc); # 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. 
+3
source

Using strings as links violates the strict pragma that you should always use. You better use a hash if you want to do it right:

 use strict; use warnings; my %hash; $hash{"var_a"} = "a"; print $hash{"var_a"},"\n"; 
0
source

All Articles