How to write on different output files with each loop iteration? (Perl)

advertisements

I have a hash of hashes of hashes in Perl called data with first level keys: F, NF and S (basically, %data={'F' => ..., 'NF' => ..., 'S' => ...})

At the beginning of my code I open 3 output handles:

open (my $fh1, ">>", $filename1) or die "cannot open > $filename1: $!";
open (my $fh2, ">>", $filename2) or die "cannot open > $filename2: $!";
open (my $fh3, ">>", $filename3) or die "cannot open > $filename3: $!";

Then, while my code runs, it populates the hash of hashes of hashes and, at the very end, I want to print the resulting hash of hashes for each key 'F', 'NF' and 'S' into a separate file (identified by the three file handles that I have defined in the beginning.) I'm not really sure how to do this. I have tried the following: right before the foreach loop in which I print the hash, I have defined

my @file_handles=($fh1, $fh2, $fh3);
my $handle_index=0;

and in each iteration of the hash I write to file by using

print $file_handles[$handle_index] "$stuff\n";

However, when I try to run the code, it tells me string found where operator expected It's my understanding that I'm not telling him correctly which file handle he should use. Any suggestions?


I seem to be able to replicate your problem by using a file handle stored in an array. Perhaps this is not possible, though I could have sworn I have seen it used before.

>perl -lwe"open $x, '>', 'a.txt' or die $!; @x = ($x); print $x[0] 'asd';"
String found where operator expected at -e line 1, near "] 'asd'"
        (Missing operator before  'asd'?)
syntax error at -e line 1, near "] 'asd'"
Execution of -e aborted due to compilation errors.

The same goes for using a hash. Possible workarounds would be:

You can skip the indirect object notation and use:

$file_handles[$index]->print("$stuff\n")

Or you can use a Perl-style loop instead to print:

for my $fh (@file_handles) {
    print $fh "$stuff\n";
}

Indirect object notation is when you put the object -- in your case a file handle -- before the function call, like so:

my $obj = new Module;

Instead of traditionally:

my $obj = Module->new;

More information about indirect object notation in perldoc perlobj