Aristotle Pagaltzis wrote:
>The code never explicitly prints to a particular handle and doesn't call
>out, so playing the dup/reopen game seems unnecessary to me.

If the requirement then is "capture whatever's written to the ambient
selected file handle", that's easier to achieve than "capture whatever's
written to STDOUT".  But an awful lot of code doesn't distinguish between
those two destinations, so for code to switch between the two in a later
edit is quite likely.  Especially if writing to the selected file handle
rather than STDOUT was later deemed a bug.  The test would backfire
quite confusingly if it only captured half the output as a consequence.

>Out of all these lines, only the last two actually have an effect.

Actually the first close has an effect too.  It is necessary to close
STDOUT before it can be reopened as a string buffer.

>Hm, even better catch. There is no way I can think of doing this with
>the select-based approach, nor with dup/reopen without involving XS;

The End module uses a pure Perl mechanism (DESTROY on a blessed object)
to indirectly cause arbitrary Perl code to execute during unwinding.
For a dependency-free approach, its mechanism can be duplicated in just
a handful of lines of code.  Actually there's good reason to duplicate it
anyway, so that you can modify it to localise the magic status variables
($., $@, $!, $^E, $?) in the destructor.

Your "local *STDOUT" is a valid approach where applicable.  Preferable to
any End-like mechanism in those cases.  It incidentally leaves *STDOUT{IO}
empty, so that an explicit close is no longer required before the reopen.

-zefram

Reply via email to