Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Re: How can I use the value of a scalar as the name of an array variable?

by runrig (Abbot)
on Nov 29, 2000 at 21:59 UTC ( [id://43969]=note: print w/replies, xml ) Need Help??


in reply to How can I use the value of a scalar as the name of an array variable?

One, rather direct, answer: Use symbolic references.

Another, possibly better, answer: Use a hash of arrays instead.

There are a couple issues with using symbolic references for this. One is that symbolic references only work with global variables, so you'll need to declare them with our rather than my. Another is that you'll have to turn off strict refs when accessing the reference. Note that, with this approach, the data file essentially contains variable names! One consequence of this is that if any data row contains a name not declared in your program, you will get a fatal runtime error. Another consequence, which is more of a security hole, is that you could munge your run-time environment if you have a bad data, like

ENV foo INC bar

This program illustrates the symbolic ref approach:

use strict; our( @fruit, @meat, @dairy ); while (<>) { chomp; my( $category, $item ) = split /\t/; no strict 'refs'; push @$category, $item; } print "Fruits are: @fruit\n";
The hash-of-arrays approach is safer, and arguably cleaner, though potentially more code-heavy:
use strict; my %food; while (<>) { chomp; my( $category, $item ) = split /\t/; push @{$food{$category}}, $item; } print "Fruits are: @{$food{'fruit'}}\n";
Lastly, here's a solution using the hash-of-arrays approach but preserving your desire to put each food item into an array named for the corresponding category. To keep the data clean, the category names are normalized on input, and unrecognized category names are discarded.
use strict; my( @fruit, @meat, @dairy ); my %food; $food{'fruit'} = \@fruit; $food{'meat'} = \@meat; $food{'dairy'} = \@dairy; while (<>) { chomp; my( $category, $item ) = split /\t/; $category = lc $category; # normalize next unless exists $food{$category}; # skip unknown push @{$food{$category}}, $item; } print "Fruits are: @fruit\n";

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://43969]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (2)
As of 2024-04-20 03:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found