#!/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 a? This seems like very unexpected behaviour to me.
I'm trying to use a variable with a substituted name. In practice, I cannot just not declare the variable, since the assignment is being done in a forloop and thus has different lexical scope.
In an <EQN> or <eqn> tag, include an assignment statement like the following: $ variable = value ; where variable is the variable name and value is the value to be assigned.
The most commonly used special variable is $_, which contains the default input and pattern-searching string. For example, in the following lines − #!/usr/bin/perl foreach ('hickory','dickory','doc') { print $_; print "\n"; }
A Perl variable name starts with either $ , @ or % followed by zero or more letters, underscores, and digits. Perl supports 3 kinds of variables: Scalars contain a single string or numeric value. The variable name must start with a $ . Arrays contain a randomly accessed ordered set of values.
@ is used for an array. In a subroutine or when you call a function in Perl, you may pass the parameter list. In that case, @_ is can be used to pass the parameter list to the function: sub Average{ # Get total number of arguments passed. $ n = scalar(@_); $sum = 0; foreach $item (@_){ # foreach is like for loop...
Please note that this has NOTHING to do with the fact that you are using variables to contain the name of other variable.
The reason this doesn't work is because ${"var_a"}
construct in reality refers to a package level variable $main::var_a
.
Since $var_a
is declared as a lexical variable, it's a DIFFERENT identifyer, 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 noted, while there is a good explanation for why what you are trying to do doesn't work, WHAT you are doing is likely the wrong approach. You should almost NEVER use this method unless there's no better way; without your problem it's not clear what the better way is but most likely would be a hash like TLP's answer says.
If you want a symbolic reference, 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 references for this purpose because they are unnecessary and likely very harmful in the context of your question. For more information, see Why it's stupid to 'use a variable as a variable name'?. There is almost always a better way to do this, one way is to make sub_a
and var_a
arrays, where sub_a
is the key for var_a
. It is good practice to always lock 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(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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With