[Israel.pm] Another newbie question - Hashes

Gaal Yahas gaal at forum2.org
Thu Feb 5 03:16:11 PST 2004


On Wed, Feb 04, 2004 at 12:01:29AM +0200, Yosef Meller wrote:
> |>### BEGIN ###
> |>open(FILE, "<file");
> |>my $file = do{ local $/; <FILE> };
> |>close(FILE);
> |>my %hash = map { split(/\s+/, $_, 2) } split (/\n/, $file);
> |>### END ###
> |
> |
> | Well, if you're already willing to read the whole file to memory why
> | don't you just use <> in list context:
> |
> |     open my $fh, "filename" or die "$0:open:$!";
> |     my %hash = map { split(/\s+/, $_, 2) } <$fh>;
> |     close $fh or die "$0:close:$!";      # or simply let $fh go out of
> scope
> |
> 
> This is starting to look like a game of Perl Golf... Here's my try:
> 
> open(STDIN,"filename")or die "$0:open:$!";
> /^(\S*) (.*)/ && $hash{$1}=$2 for(<>);
> close STDIN or die "$0:close:$!";

The point was that the previous answer was doing unecessary
stuff, such as reading the whole file to a single variable. I don't
think "local $/" (which is wrong, btw--it should be "local $/ = undef")
is newbie material.

If you're going for code that's easy for a beginner to grasp, this is
much clearer:

     while (<FILE>) {
	     my($key, $value) = split /\s+/, $_, 2;
		 $hash{$key} = $value;
	 }

And is actually *better* than the original answer, because it keeps
memory usage to a minimum. It is also more readily extensible: if you
want to add code for skipping comment lines or blank lines, or warning
about invalid lines--all of which are perfectly reasonable real-life
needs--it is pretty clear where to put them.

-- 
Gaal Yahas <gaal at forum2.org>
http://gaal.livejournal.com/



More information about the Perl mailing list