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

Hi, I need to redirect stdout for a while in a subroutine, so I did this:
sub generate_post { #need to redirect STDOUT open(SAVE_OUT, ">&", STDOUT); open(STDOUT, "> $POST_FILE") || die "Can't redirect stdout"; more code goes here... #end of the subroutine: #need to restore STDOUT(!?) close(STDOUT); open(STDOUT, ">&", SAVE_OUT);
but this generates the following warning in perl v5.8.8:
Name "main::SAVE_OUT" used only once: possible typo at ./part2.pl line + 332 (#1) (W once) Typographical errors often show up as unique variable nam +es. If you had a good reason for having a unique name, then just menti +on it again somehow to suppress the message. The our declaration is provided for this purpose. NOTE: This warning detects symbols that have been used only once s +o $c, @c, %c, *c, &c, sub c{}, c(), and c (the filehandle or format) are con +sidered the same; if a program uses $c only once but also uses any of the +others it will not trigger this warning.
How can I get rid of this warning?

Replies are listed 'Best First'.
Re: getting rid of a warning
by moritz (Cardinal) on Jan 21, 2008 at 21:31 UTC
    You can use a lexical file handle:
    open(my $save_out, '>&', STDOUT);

    Or you can disable the warning in a small scope:

    no warnings "once";
      Thank you, moritz. That was a stupid problem. Indeed, just using a "my $save_out" variable solved it.
Re: getting rid of a warning
by hipowls (Curate) on Jan 21, 2008 at 21:38 UTC

    If you change use a lexical variable for for SAVE_OUT then the warning goes away. It is also safer, you never know when there will be another SAVE_OUT somewhere else in the code and data mysteriously disappears.

    open( my $SAVE_OUT, ">&", STDOUT ); open( STDOUT, "> $POST_FILE" ) || die "Can't redirect stdout"; #more code goes here ... #end of the subroutine: #need to restore STDOUT(!?) close(STDOUT); open( STDOUT, ">&", $SAVE_OUT );

    Update: There are some fast monks out there;)

      >>If you change use a lexical variable for for SAVE_OUT then >>the warning goes away. It is also safer
      yep, that's right.
Re: getting rid of a warning
by Jenda (Abbot) on Jan 22, 2008 at 04:25 UTC

    Are you sure you need to change the STDOUT? Any chance you actually need to change the select()ed filehandle?

    open my $FH, '>', $POST_FILE or die "Can't redirect STDOUT"; my $oldFH = select($FH); ... select($oldFH);
    Of course this depends on whether you need to change the STDOUT for a subprocess or want to change where print "foo\n"; goes. In the later case you'd rather use the select(). Keep in mind that the select()ed filehandle may already be changed and then your STDOUT change will not have any effect.

Re: getting rid of a warning
by aquarium (Curate) on Jan 21, 2008 at 21:38 UTC
    you could also do as the warning suggests
    SAVE_OUT;
    should do the trick
    the hardest line to type correctly is: stty erase ^H