Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

Recursively changing STDOUT

by casiano (Pilgrim)
on Sep 16, 2007 at 12:20 UTC ( #639244=perlquestion: print w/replies, xml ) Need Help??
casiano has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

I need to write some recursive subroutine that in each entry has to

  1. save STDOUT and STDERR,
  2. change it to redirect them to some files,
  3. do something with them and call itself under the apropriate conditions
  4. recover the old values.
I know how to do it using "old style" with the ">&" descriptor. I.e. something like:
my $log = ...; my $err = ...; open(SAVEOUT, ">&STDOUT") or die ... open(STDOUT,"> $log") or die .. open(SAVEERR, ">&STDERR") or die ... open(STDERR,"> $err") or die ..
but I need to use lexical variables $SAVEOUT, and $SAVEERR instead of global variables. The problem being that to recover the old values I have now:

open(STDOUT, ">&SAVEOUT"); open(STDERR, ">&SAVEERR");

I assume that this construction will not work If I use it with lexical variables? i.e.

open(STDOUT, ">&$SAVEOUT"); open(STDERR, ">&$SAVEERR");

How can I do it?



Replies are listed 'Best First'.
Re: Recursively changing STDOUT
by shmem (Chancellor) on Sep 16, 2007 at 13:13 UTC
    This sounds like an XY Problem to me. Are you expicitly doing
    print STDOUT $foo;

    somewhere? Or are you just printing to "the default filehandle" as in

    print $foo;

    without specifiying it?

    If the latter is the case, you'll probably be better of with select and using lexical filehandles.

    sub prepare_foo_print { my ($foo, $file) = @_; open my $fh, '>>', $file or die "bummer: $!\n"; my $oldfh = select $fh; # currently opened $file now is default filehandle # (instead of STDOUT) print_whatever ($foo); select $oldfh; } sub print_whatever { print shift; }


    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: Recursively changing STDOUT
by Sidhekin (Priest) on Sep 16, 2007 at 12:30 UTC

    moritz gave you half the answer. The one thing remaining, is reopening STDOUT, STDERR with the $SAVEOUT, $SAVEERR. The three-argument open covers that:

    open(STDOUT, '>&', $SAVEOUT) or die ... open(STDERR, '>&', $SAVEERR) or die ...

    print "Just another Perl ${\(trickster and hacker)},"
    The Sidhekin proves Sidhe did it!

Re: Recursively changing STDOUT
by moritz (Cardinal) on Sep 16, 2007 at 12:22 UTC
    You can use lexical variables as file handles:

    open (my $saveout, ...);

      Thanks Moritz,

      But to recover the old values I have now:

      open(STDOUT, ">&SAVEOUT"); open(STDERR, ">&SAVEERR");

      ¿Can I use this with lexical variables? i.e.

      open(STDOUT, ">&$SAVEOUT"); open(STDERR, ">&$SAVEERR");

      It will not produce a interpolation of the filehandle?


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://639244]
Approved by moritz
[erix]: who can explain to me why Primary Key Fragmentation (whatever it may be) might be a problem?
[jedikaiti]: Pretty!
[erix]: ( TBH, I think it's a load of bull -- but maybe I'm mistaken )
[erix]: Hey that's Hungary - wave down ambrus and tell him to reboot his systems!
[choroba]: it might be a problem if you expect to reach the maximal possible value soon without squashing the ids
[erix]: that's really impossible with bigint
[erix]: and the site is still only 'hopefully' active :)

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (5)
As of 2017-06-23 15:42 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (550 votes). Check out past polls.