Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Combining 2 variable?

by Krillian (Initiate)
on Aug 31, 2014 at 12:06 UTC ( #1099114=perlquestion: print w/replies, xml ) Need Help??
Krillian has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, Not sure exactly what this is called so cannot find a tutorial. Here is the code:

$a3 = "Hello"; $b = "a"; $c = "3"; $d = "${$b.$c}"; print $d; # $d should be prints as Hello

This works fine, but if I change it a little:

$a[3] = "Hello"; $b = "a"; $c = "[3]"; $d = "${$b.$c}"; print $d; # $d should be prints as Hello

It no longer works... What am I doing wrong?
Any help would be very much appreciated and thank you very much in advance!

Replies are listed 'Best First'.
Re: Combining 2 variable?
by AppleFritter (Priest) on Aug 31, 2014 at 17:11 UTC

    To add yet another answer to your question - the reason why this isn't working is that symbolic references can only be used for the name of a variable. You may think that in the second example, you have a variable called "a[3]" containing the string "Hello", but you don't; what you actually have is an array called "a", and an element in that array at index 3 containing that string.

    Simply put, you cannot refer to individual array elements by way of a symbolic reference. That said, however, you can use a symbolic reference to the array itself, so the following works:

    $a[3] = "Hello"; $b = "a"; $c = "3"; $d = $$b[$c]; print $d;

    But again, this is generally a bad idea. In addition to what others have said, keep in mind that symbolic references can only refer to package variables, not lexicals (i.e. variables declared with my). As a result, symbolic references are by necessity forbidden when use strict is in effect.

    And speaking of which, you should always use use strict; it'll catch many bugs for you.

    Technically, it's possible to turn strict references off by saying no strict 'refs', without affecting the rest of what use strict does. Nonetheless, avoid using symbolic references. Perl gives you enough rope to hang yourself with, but doing so is still not a good idea.

Re: Combining 2 variable?
by choroba (Chancellor) on Aug 31, 2014 at 12:11 UTC
Re: Combining 2 variable?
by Laurent_R (Abbot) on Aug 31, 2014 at 12:33 UTC
    This is called a symbolic reference, and you most probably want to avoid it altogether (this was OK in Perl 4, it still works in Perl 5 (for back-compatibility reasons), but don't do it, it is just a mess). Use a hash instead.
Re: Combining 2 variable?
by LanX (Chancellor) on Aug 31, 2014 at 12:46 UTC

    Better read the link brother Choroba gave you and use this code instead.

    $HoA{a}[3]=“hello"; print $HoA{a}[3];

    See perldsc for details about nested data.

    HTH :)

    Cheers Rolf

    (addicted to the Perl Programming Language and ☆☆☆☆ :)


    symbolic refs don't seem work with nested data, the only way to make your code "work" is

     $d = eval "$b$c"

    please note that you forgot the $ sigil in $b ='$a' ( or $b ="\$a" if you need double quotes)

Re: Combining 2 variables?
by Athanasius (Chancellor) on Aug 31, 2014 at 16:00 UTC
Re: Combining 2 variable?
by davido (Archbishop) on Aug 31, 2014 at 23:48 UTC

    There is nothing elegant, or smart about doing this, but because we're playing with Perl, it is possible:

    $a[3] = "Hello"; $b = 'a'; $c = '[3]'; $d = eval "\$$b$c"; print "$d\n";

    Output: Hello. Hopefully the fact that this violates strict 'refs', strict 'vars', and requires string eval should be enough warning flags to dissuade using the construct.

    Here's how it works. First, we assign a value to $a[3]. Then we construct a string that looks like "$a[3]" using a component that looks like "a", and a component that looks like [3]. Then we evaluate that string as if it were code. The code is an expression returning the value stored in @a's fourth element.


      > this violates strict 'refs', strict 'vars',

      To be precise: eval doesn't violate strict 'refs' and strict 'vars' is easily calmed with my declarations ( though the OP never used strict )...

      > perl use strict; use warnings; my @a; $a[3] = "Hello"; my $b = 'a'; my $c = '[3]'; my $d = eval "\$$b$c"; print "$d\n"; __END__ Hello

      Cheers Rolf

      (addicted to the Perl Programming Language and ☆☆☆☆ :)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1099114]
Front-paged by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2017-02-21 03:13 GMT
Find Nodes?
    Voting Booth?
    Before electricity was invented, what was the Electric Eel called?

    Results (306 votes). Check out past polls.