Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number

Hash of output file handles

by graff (Chancellor)
on Jul 29, 2004 at 20:38 UTC ( #378504=snippet: print w/replies, xml ) Need Help??
Description: Having just tried this for the first time, I found the results... er, instructive. I'm sure there's an explanation for this somewhere in the man pages, but I haven't found it yet. The issue centers on how Perl parses the first token following "print".

use strict;
use IO::File;  # though you don't have to in 5.8, of course

my %fh_hash;

for ( qw/foo bar baz/ )
    $fh_hash{$_} = new IO::File;
    $fh_hash{$_}->open( "> $_.txt" ) or die "$_.txt: caramba: $!";

    # the next line, if uncommented, will produce a syntax error:
    # print $fh_hash{$_} "testing output to $_\n";

    # but doing it this way is okay, and it works:
    print {$fh_hash{$_}} "testing output to $_\n";
Replies are listed 'Best First'.
Re: Hash of output file handles
by gaal (Parson) on Jul 29, 2004 at 20:48 UTC
    perldoc -f print says this:
      Note that if you’re storing FILEHANDLES in an array or other expression, you will have to use a block returning its value instead:
      print { $files[$i] } "stuff\n"; print { $OK ? STDOUT : STDERR } "stuff\n";
Re: Hash of output file handles
by thor (Priest) on Jul 30, 2004 at 03:58 UTC
    This sort of thing becomes immensely useful when you create your files "on the fly". A contrived example is in order:
    use strict; use warnings; my %fh; foreach (1..1000) { my $num = int(rand() * 10000); my $first_char = substr($num, 0, 1); $fh{$first_char} || open($fh{$first_char}, ">$first_char.out") or die $!; print {$fh{$first_char}} "$num\n"; }


Re: Hash of output file handles
by zentara (Archbishop) on Jul 30, 2004 at 13:35 UTC
    Interesting timing... I was just working this out too....found the answer on google. :-) Anyways, just for kicks, here is the way I used it.... I had a few dictionary files, which I wanted to split and merge into "alphabetical files" , like a, b, c, etc so I could search for a word faster. So I need to open filehandle variables pointing to a..z.
    #!/usr/bin/perl use warnings; use strict; my $file = shift; open(FH, "< $file") or die $!; my %fh; foreach my $let('a'..'z'){ open( $fh{$let}," >> letters/$let"); } while(<FH>){ my $count = 0; my $word = $_; chomp $word; $word = lc $word; $word =~ s/[[:^print:]\s+]+//g; #only printable characters #skip words with apostrophe, dashes, spaces, or a .w ending my $word1 = $word; $count = $word1 =~ tr/\'-_ &,.0-9//; if($count > 0){next} my $let = substr($word, 0, 1); if (!defined $fh{$let}){print $word;next} else{ print { $fh{$let} } "$word\n";} } __END__
    and then to "uniqify the files
    #!/usr/bin/perl use warnings; use strict; foreach my $file('a'..'z'){ system("sort -u letters/$file > letters/$file.txt"); } __END__

    I'm not really a human, but I play one on earth. flash japh
Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: snippet [id://378504]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2020-10-20 07:23 GMT
Find Nodes?
    Voting Booth?
    My favourite web site is:

    Results (209 votes). Check out past polls.