Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Using variables in array names

by Lhamo_rin (Friar)
on Aug 05, 2005 at 12:05 UTC ( [id://481212]=perlquestion: print w/replies, xml ) Need Help??

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

Fellow monks, Is there someway to use a scalar value in an array name? For example, I would like to do something like:
my $point1 = 'valpt'; my @use_[$point1];
The result being an array named @use_valpt.

Replies are listed 'Best First'.
Re: Using variables in array names
by gellyfish (Monsignor) on Aug 05, 2005 at 12:16 UTC
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Using variables in array names
by polypompholyx (Chaplain) on Aug 05, 2005 at 12:18 UTC

    Yes, but you probably don't want to do it:

    no strict 'refs'; my $point1 = 'valpt'; @$point1 = (1,2,3); # symbolic reference print @valpt;

    Or (your specific request):

    no strict 'refs'; my $point1 = 'valpt'; eval "\@use_$point1 = (1,2,3)"; print @use_valpt;

    For several security and bug-hunting reasons, this is a very bad idea. What you probably want is a hash instead...

    my $point1 = 'valpt'; my @array = (1,2,3); $foo{ "use_$point1" } = \@array; # hard reference to array stored in hash %foo print @{ $foo{ 'use_valpt' } }; # dereference arrayref stored in %foo under 'use_valpt' key

    You can then access your data by the name chosen in $point1 without worrying about creating global variables all over the place. Have a look at perlref.

      Why the eval???
      no strict 'refs'; my $point1 = 'valpt'; eval "\@use_$point1 = (1,2,3)"; print @use_valpt;
      can be written as:
      no strict 'refs'; my $point1 = 'valpt'; @{"use_$point1"} = (1,2,3); print @use_valpt;
        Because I am being particularly dim today. You're quite right: using eval is unnecessary, and may well be like handing a box of matches to a kid whose already playing with petrol. I shouldn't have mentioned it :)
Re: Using variables in array names
by blazar (Canon) on Aug 05, 2005 at 12:09 UTC
    What you want is called a 'symref' which is short for "symbolic reference", deprecated and disallowed under use strict 'refs';, which you should have on always (use strict; comprises the former).

    You can still use them, if you really know what you're doing. But doing so amounts to mangling with a special hash, namely the symbol table. Use a "real" hash, instead and you're fine.

      Use a "real" hash, instead and you're fine.
      I beg to differ. Using a 'real' hash subjects you to some of the same problems you face when using symbolic references. Biggest problem: making typos.
      use warnings; no strict 'refs'; my $point1 = 'valpt'; @{"use_$point1"} = ("foo", "bar"); ... my $var = 'valpt'; # Oops, typo. push @{"use_$var"}, "baz"; # Silently does the wrong thing. use strict 'refs'; my $point1 = 'valpt'; my %use; @{$use{$point1}} = ("foo", "bar"); ... my $var = 'valpt'; # Oops, typo. push @{$use{$var}}, "baz"; # Silently does the wrong thing.
      Using hash keys as variable names is only marginally better than using symbolic references. (The advantage mainly being you won't accidentely overwrite important package variables - which in this case, given there are no non-user variables starting with 'use', isn't a serious risk). You still got to be careful to be "fine".
        Howdy!

        Beg all you want. You won't get any... :)

        Using hash keys with variable names is so much safer than using symbolic references. The biggest problem with symbolic references is polluting the package namespace.

        If you have a data structure with elements whose name is only going to be known at runtime, you have little choice but to use a hash. It's the "right" data structure to use. You have to be responsible for the integrity of the way you manage your keys.

        yours,
        Michael
        In fact they're almost the same, since under the hood, the creation of a symref populates the symbol table, which is 'only' a clever global hash anyway. It'd be interesting to know what the OP wanted to use the code for, since there may well be a nicer solution: the variable names look like they might be something to do with a multidimensional array, which could probably be handled in a tidier way.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://481212]
Approved by Tanalis
Front-paged by bofh_of_oz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (5)
As of 2024-04-23 16:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found