alienhuman has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I've got a hash that looks something like this:

%hash = { 'key1' = '$foo', 'key2' = '$bar', 'key3' = '$baz' }

Is there a way to get the value of key1, key2 or key3 in such a way that perl interpolates $foo, $bar or $baz respectively?

If I do:

my $not_interpolated = $hash{key1}

$not_interpolated is equal to the string "$foo" and not the value of $foo.

AH

Replies are listed 'Best First'.
Re: interpolate variable in a hash?
by broquaint (Abbot) on Sep 15, 2003 at 16:09 UTC
    You could just not put the values in single quotes and have them interpolate e.g
    my($foo, $bar, $baz) = qw/ one two three /; ## note the use of parens and *not* curly braces ## as they create an *anonymous hash reference* my %hash = ( key1 => $foo, key2 => $bar, key3 => $baz, ); print $hash{key1}; __output__ one
    Although you probably want to interpolate values when you access them (i.e not when the hash is created), so just create a references to the respective variables e.g
    my($foo, $bar, $baz) = qw/ one two three /; my %hash = ( key1 => \$foo, key2 => \$bar, key3 => \$baz, ); ## must dereference to get value print ${ $hash{key1} }, "\n"; $foo = 'something else'; print ${ $hash{key1} }, "\n"; __output__ one something else
    Although that looks prime for a quick Tie::OneOff
    use strict; use Tie::OneOff; my($foo, $bar, $baz) = qw/ one two three /; my %hash = ( key1 => \$foo, key2 => \$bar, key3 => \$baz, ); tie my %hash2, 'Tie::OneOff' => sub { ${ $hash{$_[0]} } }; print $hash2{key1}, "\n"; $foo = 'something else'; print $hash2{key1}, "\n"; __output__ one something else
    Ain't perl neat?
    HTH

    _________
    broquaint

Re: interpolate variable in a hash?
by hardburn (Abbot) on Sep 15, 2003 at 16:08 UTC

    You can make references to the variables instead. You'll have to do a little dereferencing in your print statement.

    %hash = ( key1 => \$foo, key2 => \$bar, key3 => \$baz, ); print "Bar: ${ $hash{key2} }\n"; $bar++; print "Bar: ${ $hash{key3} }\n";

    I've tested similar code on my machine.

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    Note: All code is untested, unless otherwise stated

Re: interpolate variable in a hash?
by ctilmes (Vicar) on Sep 15, 2003 at 16:01 UTC
    Use eval:
    my $interpolated = eval "$hash{key1}";
    Update: Caveat -- I answered your question, but you really should give thought to other ways of accomplishing what you are trying to do. Things like eval of strings can get you into trouble if you don't really know what you are doing.