develooper Front page | perl.perl5.porters | Postings from February 2003

binmode(FH => ":layer") should overwrite the previous layer

Thread Next
Dan Kogai
February 26, 2003 00:51
binmode(FH => ":layer") should overwrite the previous layer
Message ID:
Nick XS and Porters,

   I have painfully learned that binmode(FH => ":layer") STACKS layer 
instead of overwriting the layer.  In other words,

	binmode(FH => ":first"); binmode(FH => ":second");


	binmode(FH => ":first :second");

Nick, I think this is rather a feature instead of a bug but see this.

package Encode::ROT13;
use base qw(Encode::Encoding);
sub encode($$;$){
     my ($obj, $str, $chk) = @_;
     $str =~ tr/A-Za-z/N-ZA-Mn-za-m/;
     $_[1] = '' if $chk; # this is what in-place edit means
     return $str;
# Jr pna or ynml yvxr guvf;
*decode = \&encode;

package Module;
binmode STDOUT => ":encoding(rot13)";

use Module;
# binmode STDOUT => ":encoding(rot13)"; # Comment me out and see!
print "Perl\n";

With binmode() in commented out, prints "Crey", just as 
expected.  But when you uncomment that, it magically prints "Perl" !

This counterintuitive nature of binmode() was accidentally found by 
SUGAWARA Hajime <> when he tried to 'use encoding 
"euc-jp";' both in his module and script.  Since implicitly 
binmode()s STDIN and STDOUT, something totally unexpeded happened.

For the time being I have made a patch to so it inimport()s 
before import()s (Actual patch right after the signature) to make it 
behave as expected.  But considering the facts:

* That filehandles are global -- what if the modules called installs 
the layer and the user of the module has no idea that it does?
* There is no known way to tell what layers a given filehands are in -- 
so you can't sensibly binmode(FH => ":pop") ?

the behavior of binmode() should be modified so that it overwrites 
instead of stacks.

Dan the Encode Maintainer

diff -u -r1.41
--- 2003/02/06 01:52:11     1.41
+++ 2003/02/26 07:39:21
@@ -39,6 +39,7 @@
         require Carp;
         Carp::croak("Unknown encoding '$name'");
+    __PACKAGE__->unimport; # clean up binmode
      $name = $enc->name; # canonize
      unless ($arg{Filter}) {
         $DEBUG and warn "_exception($name) = ", _exception($name);

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About