Flawless_koder has asked for the wisdom of the Perl Monks concerning the following question:

mod_perl gives us the ability to open a filehandle with:
PerlLogFile logs/bla Thermeon::LogHandles::bla
In my PerlPostReadRequestHandler I want to add this to a hash:
'image' => \*Thermeon::LogHandles::Images
but I'm having serious trouble using it... When I do:
warn $files{ $self->{_filetype} };
I do get GLOB(x) as I would expect ... but then:
print *{ $files{ $self->{_filetype} } } $entry;
throws:
"Scalar found where operator expected"
Can anyone help me, please?

Replies are listed 'Best First'.
Re: Filehandles in a Hash
by jmcnamara (Monsignor) on Jan 13, 2003 at 09:35 UTC

    You don't need to dereference the filehandle with *. If you leave it out the code should work:
    #!/usr/bin/perl -w use strict; open TMP, "> file.tmp" or die "Couldn't open file: $!\n"; my %hash; $hash{tmpfile} = \*TMP; print {$hash{tmpfile}} "hello, world\n";

    --
    John.

Re: Filehandles in a Hash
by ihb (Deacon) on Jan 13, 2003 at 13:32 UTC
    What Perl actually is using when giving you the  print FH $foo; syntax is the indirect object syntax. Often hated, with good reasons. However, for print and printf it's still used a lot and personally I prefer to use it there too, but that's probably the only exception.

    Anyway, to the real issue here. You have the filehandle stored in something that's not a plain scalar. Knowing that the syntax above is OO syntax, it can be rewritten to
    use IO::Handle; $files{$self->{_filetype}}->print($entry);
    and it should work as expected. (Here I wonder what's really going on though. Because not only does print FH EXPR work without loading IO::Handle. You can also parenthesize it in a way you normally can't do with indirect object syntax: print(FH EXPR). Compare to parse($html_parser $chunk).)

    However, you might not want to do that. Looking at the Perl grammar (where else is this documented, except as a brief note in perlfunc?) we see that the indirob (indirect object) rule can be not just a word (for classes), scalar (for objects), but also a block. (And then there's a PRIVATEREF thing that I don't know what it is. Anyone?)   print { $files{$self->{_filetype}} } $entry; But this means that print is not special in this aspect (or at least not in principle). Having a block to resolve the object can always be done. These two lines below are generally analogous:
    do BLOCK -> method(LIST); method BLOCK LIST;
    Not that I find myself wanting any of these that often though. I usually find myself doing well with just EXPR->method(LIST).

    However, I've never seen this indirect block object syntax before on anything but print/printf. Perhaps that's partly due to lack of explanation and documentation in perlobj? (Not that we want to make people start abusing indirect block object syntax, but it's needed for deeper understanding.) Or have I missed the documentation for this?

    Hope I've helped,
    ihb
Re: Filehandles in a Hash
by bart (Canon) on Jan 13, 2003 at 12:19 UTC
    If you want to use a hash item as a filehandle, just wrap it in a block. Do not follow this by a comma!

    See also the last paragraph of perlfunc:print.

    print { $files{$self->{_filetype}} } $entry;