Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

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]
[Tanktalus]: choroba: you need to auto-pull last hour of cb when you start up so the user gets some level of context. snicker :)

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (4)
As of 2017-09-19 23:24 GMT
Find Nodes?
    Voting Booth?
    During the recent solar eclipse, I:

    Results (230 votes). Check out past polls.