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

I have two scripts (b1.pl and b2.pl) saved with encoding utf8, the contents of which are shown as follows:
#b1.pl use strict; use utf8; $_="中文"; sub p{ my $_=shift; binmode STDOUT, ":encoding(gbk)"; print "$_\n"; } p($_); p($_); __END__
#b2.pl use strict; use utf8; $_="中文"; binmode STDOUT, ":encoding(gbk)"; print "$_\n";
binmode STDOUT, ":encodinig(gbk)";
binmode STDOUT, ":encoding(gbk)"; print "$_\n"; __END__
In the scripts, 中文 are two chinese characters, which are transformed by perlmonks.In my imagination, the two scripts should have the same output. However, after run under windows xp(chinese edition, edition of perl is activeperl v5.12.2 built for MSWin32-x86-multi-thread), the two scripts have differnt outputs:
e:\home\pl>perl b1.pl perl b1.pl 中文 "\x{0590}" does not map to cp936. "\x{0384}" does not map to cp936. \x{0590}\x{0384} e:\home\pl>perl b2.pl perl b2.pl 中文 中文
I don't have any idea that why the outputs of the two scripts are different. Can any body give me some hints? Thanks.

Thanks to Anynymous Monk. "encodinig" in b2.pl is my stupid typo, I've corrected it.

Replies are listed 'Best First'.
Re: weird behaviour of binmode
by ikegami (Patriarch) on Mar 18, 2011 at 07:10 UTC

    Before you fixed your typo, the second binmode in the second snippet was failing, so a second encoding layer wasn't being added, so you didn't double-encode.

    With the typo fixed, you add two encoding layers, so you double-encode the second print, so you get garbage for the second print.

    With typo fixed:

    $ perl b1.pl 中文 "\x{0590}" does not map to cp936 at b1.pl line 8. "\x{0384}" does not map to cp936 at b1.pl line 8. \x{0590}\x{0384} $ perl b2.pl 中文 "\x{0590}" does not map to cp936 at b2.pl line 7. "\x{0384}" does not map to cp936 at b2.pl line 7. \x{0590}\x{0384}
Re: weird behaviour of binmode
by Anonymous Monk on Mar 18, 2011 at 03:32 UTC
    $ perl -Mautodie=binmode -e "binmode STDOUT, rabbits" Unknown PerlIO layer "rabbits" at (eval 3) line 67. Can't binmode('STDOUT', 'rabbits'): No such file or directory at -e li +ne 1 $ perl -Mautodie=binmode -e "binmode STDOUT, encodinig" Unknown PerlIO layer "encodinig" at (eval 3) line 67. Can't binmode('STDOUT', 'encodinig'): No such file or directory at -e +line 1
    You can ignore errno "No such file or directory" part of the message, but not "Unknown PerlIO layer"