in reply to Porting Perl 5.6 to Perl 5.8 issue with self-tie

Well, a quick solution would be IO::Tee. This should be nearly a drop-in replacement. A more comprehensive solution would be Log::Log4perl.

I have no way to test this tonight, mayhapse another monk will correct me if wrong, but to assign an IO::Tee to, say, STDOUT would be done something like this:

local *STDOUT = new IO::Tee(\*STDOUT, '>file.txt');

UPDATE: No, after looking at that, I don't think that will work. This is more likely too, but there is probably a shorter way:

open STDOUT, '>&', new IO::Tee(\*STDOUT, '>file.txt');

With this method, you can do silly things like:

# Append open STDOUT, '>>&', new IO::Tee(\*STDOUT, '>file.txt'); # Save the extra file descriptor open STDOUT, '>&=', new IO::Tee(\*STDOUT, '>file.txt'); open STDOUT, '>>&=', new IO::Tee(\*STDOUT, '>file.txt');

See open for more details.

Ted Young

($$<<$$=>$$<=>$$<=$$>>$$) always returns 1. :-)

Replies are listed 'Best First'.
Re^2: Porting Perl 5.6 to Perl 5.8 issue with self-tie
by fwashbur (Sexton) on Dec 11, 2006 at 22:30 UTC
    Hi Ted,

    I had played around with IO:Tee but I was unsuccessful in getting both STDOUT and STDERR to go to the same file. You have done something slightly different here, so I might play around with that some more.

    Thanks! Rick

      Yea, even if you can get them out to the same file, it would probably be safer to use Log::Log4perl. Any, you will get a richer logging featureset.

      Ted Young

      ($$<<$$=>$$<=>$$<=$$>>$$) always returns 1. :-)
        Thanks Ted,

        Looks like we missed the boat on Log4perl. That would have been a great logging facility. Unfortunately we already have a few million lines of Perl embedded with print/printf which I need to try to get working on 5.8 without major coding changes.

        Hey guys,

        Thanks for all the input! I learned a few new things from your suggestions.

        The Log4perl package looks promising if we ever do a redesign of our system, but it is too much of a code change (would be several thousand lines).

        I continue to not be able to use tee beyond one create/kill cycle, after that I get an argument error from tee: tee: write error: Invalid argument perhaps there is an issue with my tee? Where are you guys executing tee from?

        I was able to get it to work using a combination of tie, local, and opening the logfile prior to doing it in the tie class. So the code below is working with the InstallerHandleTie I have shown in another reply:

        use InstallerHandleTie; select STDERR; $| = 1; # make unbuffered select STDOUT; $| = 1; # make unbuffered my $gfh = *STDOUT; my $geh = *STDERR; for (1, 2) { local *STDOUT; local *STDERR; my $outfile = "globlog_$_.txt"; open LOGFILE, ">$outfile"; tie *STDOUT, 'InstallerHandleTie', *LOGFILE, $gfh; tie *STDERR, 'InstallerHandleTie', *LOGFILE, $geh; print "STDOUT in $outfile\n"; warn "STDERR in $outfile\n"; untie *STDOUT; untie *STDERR; close LOGFILE; } print "outside of tie loop, I should not be in a log file\n"; warn "outside warning - not in log\n";

        Thanks! Rick