Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Hash of output file handles

by graff (Chancellor)
on Jul 29, 2004 at 20:38 UTC ( [id://378504]=CUFP: print w/replies, xml ) Need Help??

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".
#!/usr/bin/perl 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"; }

    thor

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?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (6)
As of 2024-04-18 14:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found