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

A trick I used to use was variable abstraction (holding the name of a vairable inside of a variable). For example I have a set of arrays @a, @b and @c. I have another variable which holds the name of the array I was to look at, say $x. I would set $x to 'b' and then have the array I wanted as @$x.

#!/usr/bin/perl @a = (1, 2, 3); @b = (4, 5, 6); @c = (7, 8, 9); $x = 'b'; print "@$x\n";

Now, this won't work if you use strict in your program.

My question is, what is the correct way of doing this?

Thanks!

Replies are listed 'Best First'.
Re: Variable Abstraction with strict
by toolic (Bishop) on May 27, 2011 at 19:00 UTC
    You could reorganize your data structure and use HASHES OF ARRAYS
    use warnings; use strict; my %hoa = ( a => [(1, 2, 3)], b => [(4, 5, 6)], c => [(7, 8, 9)], ); print "@{ $hoa{b} }\n"; __END__ 4 5 6

      Yes, that would work in this case, but in general, is there a correct way to perform this abstraction?

      What if I want to find the value to $$x, where $x is the name of the scaler variable I am interested in?

        Re-reading what you say you want, this seems to meet all your requirements:
        my (@a, @b, @c, @d); # create and populate arrays #Define a "Mapping hash": my %aref = (a=>@\a, b=>\@b, c=>\@c, d=>\@d ); # (Same as toolc's solution) my $x = "b"; # I want to access "@b" my $extracted_value_5_from_b = $aref{ $x }->[5]; my @entire_array_b_copy = @{ $aref{ $x } }; # Alternative, closer to the syntax you seek.. my $y = $aref{ b }; for ( @$y ){ # We are iterating through @b here ... } #-- Strict-compliant, maintainable version ... my $z=\@b; for ( @$z ){ # We are iterating through @b here ... }

             Syntactic sugar causes cancer of the semicolon.        --Alan Perlis

        Do you mean something like this ?
        perl -e "my (@a,@b,$x); @a=0..5;@b=20..25; for $x(\@a,\@b){print qq|@$ +x;\n|}"
        Prints:
        0 1 2 3 4 5;
        20 21 22 23 24 25;

             Syntactic sugar causes cancer of the semicolon.        --Alan Perlis

Re: Variable Abstraction with strict
by chromatic (Archbishop) on May 27, 2011 at 21:05 UTC
    ... what is the correct way of doing this?

    The answer to that question depends on your answer to the question "What problem are you trying to solve?"

Re: Variable Abstraction with strict
by Gulliver (Monk) on May 27, 2011 at 20:45 UTC

    Using "strict" isn't about correct or incorrect but about restricting use of some things that are powerful but error prone. What toolic showed you with the hash is the same thing that the book Programming Perl recomends in the section about 'use strict'. It says that unlike hard references, symbolic references can only refer to global variables and that the hash table way is more efficient, more readable, and less error prone. If you still want to do it you can put no strict "refs"; or use strict qw(vars subs);

Re: Variable Abstraction with strict
by LanX (Saint) on May 27, 2011 at 21:23 UTC
    real references are strict compliant!

    DB<100> @a=(1..3) DB<101> @b=(5..7) DB<102> $x=\@b DB<103> print @$x 567

    see perldoc perlreftut

    Cheers Rolf

Re: Variable Abstraction with strict
by CountZero (Bishop) on May 28, 2011 at 12:45 UTC
    The answer is simple: don't do it.

    I have never met a problem that needed to be solved by using these dangerous tricks.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      I agree with you CountZero. This can be avoided.

      Usually this is used for optimizations. Module authors use all kind of tricks that are illegal under use strict pragma.

      Mastering Perl and Advanced Perl Programming books from O'Reilly are full of these tricks. If strict doesn't agree it doesn't mean you should never touch it. :)

      Regards

      Catalin

Re: Variable Abstraction with strict
by Anonymous Monk on May 27, 2011 at 21:15 UTC
Re: Variable Abstraction with strict
by catalin.ciurea (Novice) on May 27, 2011 at 23:15 UTC
    That is called Symbolic reference and is illegal under use strict pragma. You have to temporary disable use strict and enable it again after the print statement. #!/usr/bin/perl @a = (1, 2, 3); @b = (4, 5, 6); @c = (7, 8, 9); $x = 'b'; no strict 'refs'; print "@$x\n"; use strict 'refs';