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

Hi.

I've got a Perl script with a couple of multidimensional arrays (@menu_info, @menu_sell, etc). Now, I've got a variable that defines which array to select. This one, $foo, contains a value such as "info" or "sell", etc.

And I need select an element in the correct array, using $foo's current value... $menu_$foo doesn't seem to work when trying to select the correct array.

How can this be done?

Thanks,
Ralph.

Replies are listed 'Best First'.
Re: Selecting Correct Array
by BrowserUk (Patriarch) on Aug 23, 2002 at 09:39 UTC

    My first thought is "Use a hash!". eg.

    my %menu = { info => \@menu_info, sell => \@menu_sell }; #then.. .... print $menu{info}[0]; # First thing in the @menu_info array. print $menu{sell}[0]; # First thing in the @menu_sell array.

    Update: I should have mentioned that:

    my $foo = 'info'; print $menu{$foo}[0]; # will print the first item in @menu_info as wel +l

    Update2: changed @ to $ on array element references. Thanks Tadman.


    What's this about a "crooked mitre"? I'm good at woodwork!
Re: Selecting Correct Array
by tadman (Prior) on Aug 23, 2002 at 10:25 UTC
    Like what BrowserUk said, but with a twist:
    my %menu = ( info => \@menu_info, sell => \@menu_sell, ); # ... # Select what you want my $menu = $menu{$foo}; # ... Do stuff like print $menu->[0]->[1]; print join(',', @{$menu->[1]}),"\n";
Re: Selecting Correct Array
by helgi (Hermit) on Aug 23, 2002 at 12:53 UTC
    I would like to second BrowserUK's suggestion to use a hash.

    Also to point out that symbolic references are generally a (very) bad idea and point out this article by the Dominus, detailing how and this one detailing what to do instead and why and finally this one to drive the final nail into the symbolic reference coffin.

    I hope this helps Ralph in his quest for The Truth (tm).

    Regards,
    Helgi Briem

Re: Selecting Correct Array
by RMGir (Prior) on Aug 23, 2002 at 12:20 UTC
    What you're trying to do is use "symbolic references" (a.k.a. "soft references"); you can do it like this:
    #!/usr/bin/perl -w use strict; no strict qw(refs); our @menu_info=qw(1 2 3); our @menu_sell=qw(3 4 5); foreach my $foo ("info","sell") { print "Values in \@menu_$foo: "; print join ",",@{"menu_$foo"}; print "\n"; }
    The problems are that symbolic references only work with global variables (because they have to be in the symbol table), and they're prone to errors. If you typed @{"Menu_$foo"}, you could be wondering for a long time why you get an empty array back.

    That's why "use strict;" disallows them.

    You're much better off using the hard reference approach, which is what the answers above this one recommend.
    --
    Mike

Re: Selecting Correct Array
by fglock (Vicar) on Aug 23, 2002 at 12:27 UTC

    menu_$foo works if you don't  use strict

    my (@menu_info,$foo); $menu_info[1] = "hello"; $foo = "info"; print ${"menu_$foo"}[1];
      menu_$foo works if you don't use strict
      my (@menu_info,$foo);

      No it won't.

      Symbolic references only work for globals, because lexicals (what "my" makes) don't have symbol table entries, so ${"menu_$foo"} can't find them.

      If you tried your code, you'd see it prints nothing.

      Try this instead:

      our @menu_info; my $foo; $menu_info[1] = "hello"; $foo = "info"; print ${"menu_$foo"}[1];
      But as I mentioned above, don't do this. It only works if you turn off strict 'refs', and then the compiler can't tell you if you're referencing something that's not there, as you did.
      --
      Mike