I think what is disturbing me is that the 'a' in the pack format can be a multi-bytes character.
Me too. You've gotta wonder what's going to happen more often: someone wanting pack non-encoded characters or someone accidentally packing non-encoded characters. I would say the latter, so I find it weird that it doesn't croak ("Wide char in ...") when passed non-encoded characters.
It could be a side effect of allowing pack and unpack to work with fixed-width fields, where the width is in characters rather than bytes.
my $rec_format = 'a4a5a1';
my $rec_size = 10;
binmode $fh_out, ':encoding(UTF-8)';
print $fh_out pack($rec_format, @fields);
binmode $fh_in, ':encoding(UTF-8)';
read($fh_in, my $rec = '', $rec_size);
@fields = unpack($rec_format, $rec);