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

Brethern

I have existing code, much of it going back to Perl 4.?. I now need to run both on systems running 5.004_04 and 5.8. Existing code (which didn't use strict) used a string for a file handle.

sub printSumpn{ local($handle, file) = ('RPT', '/tmp/report.txt'); myOpen($handle, $file); print $handle "hello world\n"; close($handle)} sub myOpen{ local($handle, $file) =@_; # ...do some logging and sanity checking... open($handle, ">$file")}
Coming up to 5.8, this gave various scoldings when I use strict;. Changing 'local' to 'my' and 'RPT' to *RPT seemed to fix the problem.

But under 5.004_04, setting

my $handle = *RPT;
leaves $handle undef, so it loses when it does the open (or the print).

I want to set $handle equal to a filehandle, and be able to pass $handle to a file-opening subroutine, to print, and to close. I want to do this in a way that doesn't violate strict. And in a way that works under both 5.004_04 and 5.8.

Can I do that?

thanks
throop

Replies are listed 'Best First'.
Re: Opening files in 5.004 and 5.8
by gaal (Parson) on May 11, 2007 at 21:27 UTC
    Lexical filehandles were introduced in 5.6, IIRC. You can say

    my $handle = \*RPT;

    and pass it to a subroutine in versions prior to that, though. close and friends work with that.

Re: Opening files in 5.004 and 5.8
by grinder (Bishop) on May 12, 2007 at 15:24 UTC

    To minimise the amount of code you have to change, I would just conditionally bring in the Symbol module, and call gensym to initialise your file handle, and ditch the 'RPT' stuff.

    use Symbol; sub printSumpn{ my($handle, $file) = (gensym(), '/tmp/report.txt');

    And everything will work just fine. You don't actually care about what the handle itself looks like, just that it uniquely identifies whatever it's printing to. gensym does that for you.

    • another intruder with the mooring in the heart of the Perl

      Ugh, another module for the "CPAN one-liners" file:
      sub gensym { \*{'__GEN__' . ++$__GEN__::__counter__} }
      It's a useful function, but not worth an extra dependency.
        FWIW, Symbol has been core since 5.002.

        Also see the comment on copying the glob vs. making a reference in the Symbol.pm implementation.