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

Trying to store a filehandle in a hash for some reporting. If the filehandle is NULL, then we default to STDOUT. This code is broken:
#!/usr/bin/env perl #$Name$ #$Id$ use FileHandle; my $FName = shift(@ARGV) || ""; my %uHHash; if ($FName ne "") { open($uH, ">".$FName); $uHHash{uHANDLE} = $uH; } else { $uHHash{uHANDLE} = STDOUT; } printf($uHHash{uHANDLE} "Output is here (%s) !\n","HJGKJGJHJLHL"); close($uHHash{uHANDLE}); exit(0);
Yet, assigning the handle to a temporary variable and placing that temp var into the printf works...
... my $uuh = $uHHash{uHANDLE}; printf($uuh "Output is here (%s) !\n","HJGKJGJHJLHL"); close($uHHash{uHANDLE}); exit(0);
Why? I have tried backslashing the hashed handle, backslash star, dereferencing the hashed value as scalar and hash...Mostly seeing STDOUT is scalar and FileHandle is GLOB, but this doesn't really explain the why for printf acting this way to a hash reference versus the scalared value...

Replies are listed 'Best First'.
Re: Odd Hashed Filehandle behavior
by Fletch (Bishop) on Feb 26, 2010 at 15:24 UTC

    As the docs for print explain:

    Note that if you're storing FILEHANDLEs in an array, or + if you're using any other expression more complex than a s +calar variable to retrieve it, you will have to use a block r +eturning the filehandle value instead: print { $files[$i] } "stuff\n"; print { $OK ? STDOUT : STDERR } "stuff\n";

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: Odd Hashed Filehandle behavior
by keszler (Priest) on Feb 26, 2010 at 15:30 UTC
    printf {$uHHash{uHANDLE}} "Output is here (%s) !\n","HJGKJGJHJLHL";
    From the print documentation:
    Note that if you're storing FILEHANDLEs in an array, or if you're using any other expression more complex than a scalar variable to retrieve it, you will have to use a block returning the filehandle value instead:
    print { $files[$i] } "stuff\n"; print { $OK ? STDOUT : STDERR } "stuff\n";

    Also, if reading from a filehandle stored in a hash you cannot use @x = <$hash{key}>;, you need to use @x = readline($hash{key});

      That's it!
      #!/usr/bin/env perl #$Name$ #$Id$ use FileHandle; my $FName = shift(@ARGV) || ""; my %uHHash; if ($FName ne "") { open($uH, ">".$FName); $uHHash{uHANDLE} = $uH; } else { $uHHash{uHANDLE} = STDOUT; } printf({$uHHash{uHANDLE}} "Output is here (%s) !\n","HJGKJGJHJLHL"); close($uHHash{uHANDLE}); exit(0);
      After the first reply, I tried something similar, but I see my mistake now. Thanks... jrk