Search code examples
perlfilehandle

Managing filehandles within array of hashes in perl


I have an array of hashes, which I'm filling in the following way:

# Array of hashes, for the files, regexps and more.
my @AoH;
push @AoH, { root => "msgFile", file => my $msgFile, filefh => my $msgFilefh, cleanregexp => s/.+Msg:/Msg:/g, storeregexp => '^Msg:' };

This is one of the entry, I have more like this. And been using each key-value pair of the hashes for creating files, cleaning lines from a text file and more. The thing is, I've created files in the following way:

# Creating folder for containing module files.
my $modulesdir = "$dir/temp";

# Creating and opening files by module.
for my $i ( 0 .. $#AoH )
{
    # Generating the name of the file, and storing it in hash.
    $AoH[$i]{file} = "$modulesdir/$AoH[$i]{root}.csv";
    # Creating and opening the current file.
    open ($AoH[$i]{filefh}, ">", $AoH[$i]{file}) or die "Unable to open file $AoH[$i]{file}\n";
    print "$AoH[$i]{filefh} created\n";
}

But later, when I'm trying to print a line to the filedescriptor, I got the following error:

String found where operator expected at ExecTasks.pl line 222, near ""$AoH[$i]{filefh}" "$row\n""
        (Missing operator before  "$row\n"?)
syntax error at ExecTasks.pl line 222, near ""$AoH[$i]{filefh}" "$row\n""
Execution of ExecTasks.pl aborted due to compilation errors.

And, this is the way I'm trying to print to the file:

# Opening each of the files.
foreach my $file(@files)
{
    # Opening actual file.
    open(my $fh, $file);

    # Iterating through lines of file.
    while (my $row = <$fh>)
    {
        # Removing any new line.
        chomp $row;

        # Iterating through the array of hashes for module info.
        for my $i ( 0 .. $#AoH )
        {
            if ($row =~ m/$AoH[$i]{storeregexp}/)
            {
                print $AoH[$i]{filefh} "$row\n";
            }
        }
    }

    close($fh);
}

What is wrong with the way I'm trying to print to the file? I tried printing the value of the filehandle, and I was able to print it. Also, I printed the matches with the storeregexp, successfully.

By the way, I'm working in a machine with Windows, using perl 5.14.2


Solution

  • Perl's print expects a very simple expression as the filehandle -- per the documentation:

    If you're storing handles in an array or hash, or in general whenever you're using any expression more complex than a bareword handle or a plain, unsubscripted scalar variable to retrieve it, you will have to use a block returning the filehandle value instead, in which case the LIST may not be omitted:

    In your case, you'd use:

    print { $AoH[$i]{filefh} } "$row\n";
    

    You could also use the method call form, but I probably wouldn't:

    $AoH[$i]{filefh}->print("$row\n");