To add the encoding layers to STDIN, STDOUT and STDERR, you need to use
use open ':std', ':locale';
instead of
use open ':locale';
But that doesn't just add an encoding layer to STDIN, STDOUT and STDERR; it causes the same layer to be added to file handles opened in scope by default. So we need to override that default with
open(my $fh, '>:encoding(UTF-8)', $qfn)
or
use open ':encoding(UTF-8)';
open(my $fh, '>', $qfn)
All together:
use open ':std', ':locale';
use open ':encoding(UTF-8)';
open(my $fh_txt, '>', $qfn); # Text
open(my $fh_bin, '>:raw', $qfn); # Binary
or
use open ':std', ':locale';
open(my $fh_txt, '>:encoding(UTF-8)', $qfn); # Text
open(my $fh_bin, '>:raw', $qfn); # Binary
Result:
my $s = chr(0xE9);
say $s; # U+E9 encoded as per locale
say $fh_txt $s; # U+E9 encoded using UTF-8
say $fh_bin $s; # Byte E9
(You can use binmode($fh);
instead of :raw
for binary files, if you prefer.)
export PERL_UNICODE=SAL
– Huldahuldah