IO::File->open() doesn't seem to respect use open() in the following program, which is odd to me and seems to be against the documentation. Or maybe I'm doing it wrong. Rewriting my code to not use IO::File shouldn't be difficult.
I expect the output to be
$VAR1 = \"Hello \x{213} (r-caret)";
Hello ȓ (r-caret)
Hello ȓ (r-caret)
Hello ȓ (r-caret)
But I'm getting this error: "Oops: Malformed UTF-8 character (unexpected end of string) in print at ./run.pl line 33."
That doesn't seem right to me at all.
#!/usr/local/bin/perl
use utf8;
use v5.16;
use strict;
use warnings;
use warnings qw(FATAL utf8);
use diagnostics;
use open qw(:std :utf8);
use charnames qw(:full :short);
use File::Basename;
my $application = basename $0;
use Data::Dumper;
$Data::Dumper::Indent = 1;
use Try::Tiny;
my $str = "Hello ȓ (r-caret)";
say Dumper(\$str);
open(my $fh, '<', \$str);
print while ($_ = $fh->getc());
close($fh);
print "\n";
try {
use IO::File;
my $fh = IO::File->new();
$fh->open(\$str, '<');
print while ($_ = $fh->getc());
$fh->close();
print "\n";
}
catch {
say "\nOops: $_";
};
try {
use IO::File;
my $fh = IO::File->new();
$fh->open(\$str, '<:encoding(UTF-8)');
print while ($_ = $fh->getc());
$fh->close();
print "\n";
}
catch {
say "\nOops: $_";
};
I believe what's happening here is
use openis a lexical pragma meaning it only affects calls toopen()in the same lexical scope. Lexical scope is when the code is in the same block.IO::File->openis a wrapper aroundopen()and so is callingopen()outside its lexical scope.In the example above, even though
foo()is called insideuse open's lexical scope, the code insidefoo()is outside and thus not under its effect.It would be polite if IO::File inherited open.pm. This is not trivial but possible. A similar problem plagued autodie. It was fixed and the fix could probably work in IO::File.