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

This seemed like it would be easy when I decided to do it but it turned out to be a bit more difficult than I would have thought.

Basically, I've got a file.

data.txt

that is full of data formatted like this:

name|value

and in side a script i've got a hash

%stuff (

);

I want the data to go inside the hash.
I've done this and dozens of other variations
open (OUT, "data.txt") || die "Can't open the data file"; foreach $i ($data[0], $data[1]){ chomp($i); ($short,$place) = split(/\|/,$i); %stuff = ( '$short' => '$place', ); close(OUT); }

While there are no errors that are obvious with in the scripts performance, the desired outcome does not happen.

short is supposed to filter to place.

Think of it as a word filter..

Now, it works perfectly when I actually have the hash data there in this format

'short' => 'place',

but I can't get it to properly read and covert from the data file.

Any suggestions or ideas on what I'm doing wrong?

Thanks in advance

Replies are listed 'Best First'.
Re: novice with hash/data file question
by chromatic (Archbishop) on Sep 02, 2008 at 08:25 UTC
    foreach $i ($data[0], $data[1]){

    What do you expect this to do? There's no @data in your program; what does it contain?

    '$short' => '$place',

    The key of this pair is the literal string $short and not the contents of the variable $short. Likewise the value of this pair is the literal string $place and not the contents of the variable $place. When you use a scalar variable in a double-quoted string, Perl interpolates the value of that variable in the string (that is, Perl looks up the value and inserts it into the string). There's no interpolation in single-quoted strings.

    %stuff = ( ... )

    This will overwrite the hash at each iteration of the loop. Similarly, closing your (unused) filehandle within the body of the loop will close it multiple times.

    I suspect you want a program more like:

    use strict; use warnings; open my $fh, 'data.txt' or die "Can't read data.txt: $!\n"; my %stuff; while (<$fh>) { chomp; my ($short, $place) = split /\|/, $_; $stuff{$short} = $place; } close $fh;

    ... but that's a rough guess. (Because you're a novice, let me point out gently that naming a filehandle OUT when you open it for reading will confuse people.)

      Firstly, you're brilliant....

      And the first line was part of something i copied from a different script i made a long time ago

      (apparently a year lull in practice makes what little knowledge I already had go away).

      I had tried to do this a lot of different ways and finally resorted to savaging form previous scripts in hopes of figuring it out, if only by mistake.

      Now that i see the answer written down, it makes sense.

      But yes, you were absolutely correct. I've been googling everything I could find on hashes in perl for hours. Maybe my key words correct, but I couldn't find anything on accessing data from a file through a hash. Thanks a lot.
        Use this code:
        open(FILE, '<', 'data.txt'); my %result = map {split /\|/; ($_[0] => $_[1])} <FILE>; close(FILE);
        It will fulfill all your needs :)
        What you need is to firstly read a textbook about perl carefully...
Re: noob with hash/data file question
by moritz (Cardinal) on Sep 02, 2008 at 08:19 UTC
    %stuff = ( '$short' => '$place', );

    You're constructing a new hash (with the strings $short and $place, not with the values of these variables) and override the existing hash with it.

    Instead you have to populate the hash like this: $stuff{$short} = $place

      Thanks.
Re: noob with hash/data file question
by ikegami (Patriarch) on Sep 02, 2008 at 08:18 UTC
    There are so many errors, but the first thing you should notice is that you never read from your date file. (And what a poor name for an input file handle!)