perl-unicode

Re: Determining IO layer set on filehandle

2010-01-29 10:06:43
Am 29.01.2010 um 15:37 schrieb Aristotle Pagaltzis:

* Michael Ludwig <michael(_dot_)ludwig(_at_)xing(_dot_)com> [2010-01-29 
14:20]:
Is there an alternative way to achieve what I want, maybe
involving one of the IO modules?

You may want to just dup the filehandle and then diddle the dup’d
one. You may need to `seek $origfh, (tell $dupfh), 0` afterwards.
Not sure how much other state filehandles have that you might
need to transfer, assuming that the state matters to you at all.

I don't think it does. The use case here is a server process printing
text encoded in UTF-8 to STDOUT. So we set things up the way to do just
that, which includes switching STDOUT to :utf8.

Now once in a while there is binary data to be transmitted, and we don't
want that to be encoded in UTF-8. So we'd like to switch STDOUT over to
:raw for that one particular print statement.

But as that happens in a subroutine of a module, we don't want to make
assumptions about the caller's settings on STDOUT, so we cannot fiddle
with STDOUT directly. As far as I can see, which might not be very far,
there is no way to determine the IO layers (like :raw or :utf8) applied
to a given filehandle. So we cannot save and restore these on STDOUT.

Now, dup (as in perldoc -f open) to the rescue. We dup STDOUT and tweak
the duplicate, as posted. We can use $dup to print binary data. STDOUT
does not seem to be affected by this fiddling with $dup, which itself
simply goes out of scope when the subroutine ends.

sub out_bin_good {
   open my $dup, '>&STDOUT' or die "dup STDOUT: $!";
   binmode $dup, ':raw' or die "binmode: $!";
   print $dup @_; # print binary data here
   # STDOUT unaffected by any fiddling with $dup
}

If that's all there is to it, that's cool.
-- 
Michael.Ludwig (#) XING.com