9

Possible Duplicate:
How can I use a variable as a variable name in Perl?

Is this doable? I need to change a string into variable.

Example:

If I have a variable like this:

$this_is_test = "what ever";
$default = "this";
$default = $default . "_is_test";

I want $default to take the value of $this_is_test.

Community
  • 1
  • 1
Luci
  • 3,174
  • 7
  • 31
  • 36
  • I guess I can use a hash to work this out. Yet I was wondering if there is another way. – Luci Oct 06 '10 at 10:18
  • @skimnetser: no this wont work. This will give : $default="this_is_test"; which is a string. – Luci Oct 06 '10 at 10:25
  • sorry I misunderstood the question, try this: $default= ${$default.'_is_test'}; – skimnetster Oct 06 '10 at 10:30
  • 5
    This gets asked a lot on SO: [varvarname](http://stackoverflow.com/search?q=varvarname). It's also [a Perl FAQ](http://faq.perl.org/perlfaq7.html#How_can_I_use_a_vari). – daxim Oct 06 '10 at 12:28
  • See also http://stackoverflow.com/questions/1298035/how-do-i-use-symbolic-references-in-perl – daotoad Oct 07 '10 at 08:42

2 Answers2

15

Along the lines of my other answer, whenever you find yourself adding string suffixes to a variable name, use a hash instead:

my %this = (
    is_test => "whatever",
    is_real => "whereever",
);

my $default = $this{is_test};

print "$default\n";

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'?, part 2 and part 3 by mjd.

Community
  • 1
  • 1
Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
  • Thanks, I used the hash, yet it is not wrong to learn the other ways..By the way it seems that u added an extra _ in the hash key _is_test. – Luci Oct 08 '10 at 11:46
7

As rafl said, this can be achieved through symbolic references, but they are quite dangerous (they are a code injection vector) and don't work with lexical variables (and should be using lexical variables instead of package variables). Whenever you think you want a symbolic reference, you almost certainly want a hash instead. Instead of saying:

#$this_is_test is really $main::this_is_test and is accessible from anywhere
#including other packages if they use the $main::this_is_test form 
our $this_is_test = "what ever";
my $default       = "this";
$default          = ${ $default . "_is_test" };

You can say:

my %user_vars = ( this_is_test => "what ever" );
my $default   = "this";
$default      = $user_vars{ $default . "_is_test" };

This limits the scope of %user_vars to the block in which it was created and the segregation of the keys from the real variables limits that danger of injection attacks.

Chas. Owens
  • 64,182
  • 22
  • 135
  • 226