If you want to temporarily change the PerlIO layers of a handle, your best bet might be to dup the handle.
use strict;
use warnings;
use PerlIO qw( );
sub dump_layers($*) {
my ($prefix, $fh) = @_;
my @layers = PerlIO::get_layers($fh);
print($prefix, join(', ', @layers), "\n");
}
dump_layers('before: ', STDERR);
{
open my $fh, '>&', STDERR or die $!; # Dup the handle
binmode $fh, ':encoding(UTF-8)'; # Do anything to the dup.
dump_layers('local: ', $fh);
}
dump_layers('after: ', STDERR); # The original is unaffected.
before: unix, perlio
local: unix, perlio, encoding(utf-8-strict), utf8
after: unix, perlio
The package variable itself could be replaced with the dup for the duration of the inner scope, but it shouldn't normally be needed.