Perl';s IO::文件并使用open qw(:utf8)
IO::File->open()似乎不尊重以下程序中的use open(),这对我来说很奇怪,似乎与文档不符。也许我做错了。重写我的代码以不使用IO::File应该不难 我希望输出是Perl';s IO::文件并使用open qw(:utf8),perl,unicode,perl-io,Perl,Unicode,Perl Io,IO::File->open()似乎不尊重以下程序中的use open(),这对我来说很奇怪,似乎与文档不符。也许我做错了。重写我的代码以不使用IO::File应该不难 我希望输出是 $VAR1 = \"Hello \x{213} (r-caret)"; Hello ȓ (r-caret) Hello ȓ (r-caret) Hello ȓ (r-caret) 但是我得到了这个错误:“Oops:print在./run.pl第33行的格式错误的UTF-8字符(字符串的意外结尾)。” 我觉得那根
$VAR1 = \"Hello \x{213} (r-caret)";
Hello ȓ (r-caret)
Hello ȓ (r-caret)
Hello ȓ (r-caret)
但是我得到了这个错误:“Oops:print在./run.pl第33行的格式错误的UTF-8字符(字符串的意外结尾)。”
我觉得那根本不对
#!/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: $_";
};
#/usr/local/bin/perl
使用utf8;
使用v5.16;
严格使用;
使用警告;
使用警告qw(致命utf8);
使用诊断;
使用开放式qw(:标准:utf8);
使用字符名qw(:full:short);
使用File::Basename;
my$application=basename$0;
使用数据::转储程序;
$Data::Dumper::Indent=1;
使用Try::Tiny;
我的$str=“你好ȓ;(r-caret)”;
说Dumper(\$str);
open(我的$fh,我相信这里发生的事情是使用open
是一个词法pragma,意思是它只影响对同一词法作用域中open()
的调用。词法作用域是当代码在同一块中时。IO::File->open
是open()
的包装,调用open()也是如此)
超出其词法范围
{
use open;
...same lexical scope...
{
...inner lexical scope...
...inherits from the outer...
}
...still the same lexical scope...
foo();
}
sub foo {
...outside "use open"'s lexical scope...
}
在上面的示例中,尽管foo()
在使用open
的词法范围内调用,但是foo()
内的代码在外部,因此不受其影响
如果IO::File继承了open.pm,那将是礼貌之举。这不是小事,但有可能。类似的问题也存在。修复可能在IO::File中起作用。我相信这里发生的是使用open
是一个词汇pragma,意味着它只影响对open()的调用
在同一词法作用域中。词法作用域是当代码在同一块中时。IO::File->open
是open()
的包装,在其词法作用域之外调用open()
也是如此
{
use open;
...same lexical scope...
{
...inner lexical scope...
...inherits from the outer...
}
...still the same lexical scope...
foo();
}
sub foo {
...outside "use open"'s lexical scope...
}
在上面的示例中,尽管foo()
在使用open
的词法范围内调用,但是foo()
内的代码在外部,因此不受其影响
如果IO::File继承了open.pm,这将是礼貌的。这不是小事,但可能是有问题的。类似的问题也会出现。并且修复可能在IO::File中工作。[这不是答案,而是一个不适合注释的错误通知。]
文件只能包含字节。$str
包含的值不是字节。因此
open(my $fh, '<', \$str)
[这不是一个答案,而是一个不适合评论的bug通知。]
文件只能包含字节。$str
包含的值不是字节。因此
open(my $fh, '<', \$str)
那么这就有意义了。我将重写代码以直接调用open()。谢谢。那么这就有意义了。我将重写代码以直接调用open()。谢谢。我认为这不对。使用v5.16;打开unicode字符串并使用utf8;在源文件中启用unicode。在不使用encode_utf8()的情况下读取字符串应该(并且确实如此)工作。正如您在我添加的代码中所看到的,您对它工作的看法是错误的。如果您使用:utf8
(与另一种编码相反),它将只对某些字符串工作。(当它这样做时,它应该给出一个“宽字符”警告或错误。这是Perl中的一个错误,它没有。)$fh
生成解码字符,因为它的:utf8层对流进行解码。这意味着流必须开始编码,但您正在传递一个解码字符串。上述注释中缺少:如果您使用:utf8
以外的:encoding
,它的工作频率将更低。我认为这不对。请使用v5.16;启用unicode字符串并使用utf8;在源文件中启用unicode。在不使用encode_utf8()的情况下读取字符串应该(并且确实)起作用。正如您在我添加的代码中所看到的,您认为它起作用是错误的。如果您使用:utf8
(与另一种编码相反),它将只对某些字符串起作用。(当它起作用时,应该给出一个“宽字符”警告或错误。这是Perl中的一个错误,它没有。)$fh
生成解码字符,因为其:utf8层对流进行解码。这意味着流必须开始编码,但您正在传递一个解码字符串。上述注释中缺少:如果您使用的是:utf8
以外的:encoding
,则其工作频率将更低。
codepoints ok "\x{213}" => "\x{213}" => "\x{213}"
codepoints not ok "\311" => "\311" => DIED
codepoints not ok "\x{c9}" => "\x{c9}" => DIED
bytes ok "\x{213}" => "\310\223" => "\x{213}"
bytes ok "\311" => "\303\211" => "\x{c9}"
bytes ok "\x{c9}" => "\303\211" => "\x{c9}"