Is there a way to capture a subroutine's print output to a variable so I can send it to stderr instead?

后端 未结 4 1059
离开以前
离开以前 2021-01-12 08:50

Suppose we have:

sub test {
        print \"testing\\n\";
}

If there is a case where I want to have it print to stderr instead of stdout, i

4条回答
  •  感动是毒
    2021-01-12 09:23

    Perl's dynamic scoping via local() is not often used, but this strikes me as a good application for it:

    test(); # to stdout
    {
        open(local *STDOUT, ">&STDERR") or die "dup out to err: $!";
        test(); # to stderr, locally calling it "STDOUT"
    }
    test(); # to stdout again
    

    The call to test() in the block above -- as well as to anything that test() itself might call -- will have STDOUT dynamically scoped to your duplicate of STDERR. When control leaves the block, even if by die()ing, STDOUT will be restored to whatever it was before the block

    Generalized:

    sub out2err(&) {
      my $user_block = shift;
      open(local *STDOUT, ">&STDERR") or die $!;
      $user_block->();
    }
    
    test();             # to stdout
    out2err { test() }; # to stderr
    test();             # to stdout
    

提交回复
热议问题