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

A have a STDOUT handle tied to some object (e.i. Apache or Parser::ePerl). Now I want to tie STDOUT to my own object, do my job and then restore the original 'tie' association with Apache or Parser::ePerl.

How to do it?

local(*STDOUT) do not work in this case. Why?

Replies are listed 'Best First'.
(tye)Re: Local tied FILEHANDLE
by tye (Sage) on Jan 02, 2001 at 21:04 UTC

    "do not work" is never a good description of a problem (if you want help with the problem). Please do what you should always do: Reduce the script to a very, very small script that demonstrates the problem and post the exact script, the exact input and output (including any error messages), and exactly what seems wrong about it to you. (and use strict.pm; and -w)

    Anyway, I think local(*STDOUT) would be exactly what you'd want here.

    The other suggestion of open(OLDOUT, ">&STDOUT"); doesn't seem like a useful thing to me when dealing with a tied file handle. It is execellent advise when dealing with non-tied file handles, though.

            - tye (but my friends call me "Tye")
      Well then, were it is:

      Script:

      use strict;
      
      my $bar = tie(*STDOUT, 'Bar');
      
      print "Before\n";
      test();
      print "After\n";
      
      untie(*STDOUT);
      
      sub test {
              local(*STDOUT);
      
              my $foo = tie(*STDOUT, 'Foo');
              print "In medias res\n";
              untie(*STDOUT);
      }
      
      package Foo;
      
      sub TIEHANDLE {
              my ($class) = @_;
              return bless({},$class);
      }
      
      sub PRINT {
              my ($self) = shift;
              print STDERR ("Foo::PRINT: ",@_);
      }
      
      package Bar;
      
      sub TIEHANDLE {
              my ($class) = @_;
              return bless({},$class);
      }
      
      sub PRINT {
              my ($self) = shift;
              print STDERR ("Bar::PRINT: ",@_);
      }
      
      Output:
      Bar::PRINT: Before
      Foo::PRINT: In medias res
      After
      
      Expected output:
      Bar::PRINT: Before
      Foo::PRINT: In medias res
      Bar::After
      

      It seems like STDOUT is retied to Foo and then untied. local(*STDOUT) has no effect here. Why?

        If it isn't could someone explain the following short program to me? My expectation is that after calling local the original handle should be untouched by anything that you do. This emphatically is not happening:
        test(1); test(2); sub test { my $iter = shift; my $fh = \*STDOUT; print $fh "Before local $iter\n"; local *STDOUT; print $fh "Before tying $iter\n"; tie (*STDOUT, 'Foo', $iter); print $fh "After tying $iter\n"; } package Foo; sub TIEHANDLE { my ($class) = shift; return bless([shift],$class); } sub PRINT { my ($self) = shift; print STDERR ("Foo::PRINT (tie $self->[0]): ",@_); }
        Please use code tags. They are not just for formatting, they also allow people to easily download your code and run it.

        Given an IE bug on the machine I am on right now, this is inconvenient for me, so I am unable to test my guesses as to what your problem might be...

Re: Local tied FILEHANDLE
by Daniellek (Sexton) on Jan 02, 2001 at 20:05 UTC
    I don't know if I understood You right but, maybe you need to "backup" STDOUT and then restore it... Something like:
    open(OLDOUT, ">&STDOUT"); open(STDOUT, ">foo.out") || die "Can't redirect stdout"; #doing your interesting things here... close(STDOUT); open(STDOUT, ">&OLDOUT"); #here's is your starting state.
    -- Daniellek