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

I need to read data from a small comma delimited text file, and have the data stored in a series of arrays (one for each field.) Each record needs to be accessible in the form $fieldname[$recordnumber] Instead of having to write
while (<DATA>) { ($name[$b],$address[$b],$city[$b],…) = split /\,/,$_; etc... $b++; }
I would like to be able to store the variable names in an array, ie.
@varnames =(‘name’,’address’,’city’,…)
and then somehow use this array of names to work with the split command in the same way as above. Any ideas? Thanks in advance.

Replies are listed 'Best First'.
Re: Using variable names from an array
by lhoward (Vicar) on Sep 05, 2000 at 00:47 UTC
    What't you're talking about is symbolic refrences. They are very bad and can lead to buggy and hard to maintain code.

    What you should try instead is a hash-of-arrays. See the perldsc documentation for some details and examples.

    $data{city}[2]="Albany"; etc...
(Ovid) Re: Using variable names from an array
by Ovid (Cardinal) on Sep 05, 2000 at 01:05 UTC
    To expand on what lhoward pointed out, here's some actual code that you can use (untested):
    my %data; while (<DATA>) { ($data{'name'}[$.], $data{'address'}[$.], $data{'city'}[$.]) = split /,/,$_; }
    Then, if you want the address from the third record:
    print $data{'address'}[3];
    A couple of other points to note:
    • $. is a special Perl variable which hold the current line number of the input file. There's no need for $b++ (though some may consider $. to be obfuscated).
    • You don't need to escape the comma in your regex.
    • Your regex will fail if you have a comma embedded in one of your fields. You should use something like Text::CSV if you do a lot of work with CSV data.
    Cheers,
    Ovid
Another approach
by gryng (Hermit) on Sep 05, 2000 at 08:27 UTC
    As the wise monks above pointed out, using a hash is a good idea!

    Another thing I would like to mention is the possibility of using: $data[$n]{$fieldname} Instead of: $data{$fieldname}[$n]

    I think under most situations, you would probably want the former layout. Not only is it more sensible, but it would under most situations(*) preform better.

    (*) Most situations is defined as zero overhead for the use of hashes (which I think is on the slate somewhere for future version of perl with hash use in this way), as well as entry number oriented access. That is, you generally access a particular entry, rather than a particular field.

    Enjoy!
    Gryn