perl - List::Util - 减少 - 长度 - 编码 - 问题

标签 perl list encoding utility

为什么我在第一个reduce示例中得到错误的结果?

测试.txt

__BE  
bb bbbbbbbbbbbbbbb  

aaaaaa  

测试.pl

#!/usr/bin/env perl
use warnings; use 5.012;
use open ':encoding(UTF-8)';
use List::Util qw(reduce);
use Encode;

my( @list, $longest, $len );
open my $fh, '<', 'test.txt' or die $!;
    while( my $line = readline( $fh ) ) {
    chomp $line;
    push @list, split( /\s+/, $line );
    }
close $fh;

$longest = reduce{ length($a) > length($b) ? $a : $b } @list;
$len = length $longest;
say $longest; # aaaaaa
say $len;     # 6

$longest = reduce{ length(Encode::encode_utf8($a)) > length(Encode::encode_utf8($b)) ? $a : $b } @list;
$len = length(Encode::encode_utf8($longest));
say $longest;  # bbbbbbbbbbbbbbb
say $len;     # 15

$longest = $list[0];
$len = length $longest;
for my $str (@list) {
    if ( length($str) > $len ) {
        $longest = $str;
        $len = length($str);
    }
}
say $longest; # bbbbbbbbbbbbbbb
say $len;     # 15

最佳答案

AFAICS,它甚至可能是 Perl 中的一个错误...它的行为是否正确当然并不明显。我修改了第一个reduce以打印诊断信息:

#!/usr/bin/env perl
use warnings; use 5.012;
use open ':encoding(UTF-8)';
use List::Util qw(reduce);
use Encode;

my( @list, $longest, $len );
open my $fh, '<', 'test.txt' or die $!;
    while( my $line = readline( $fh ) ) {
    chomp $line;
    push @list, split( /\s+/, $line );
    }
close $fh;

$longest = reduce { say "<<$a>>/<<$b>> : ", length($a), " : ", length($b);
                    length($a) > length($b) ? $a : $b } @list;
$len = length $longest;
say $longest; # aaaaaa
say $len;     # 6

$longest = reduce { length(Encode::encode_utf8($a)) > length(Encode::encode_utf8($b)) ? $a : $b } @list;
$len = length(Encode::encode_utf8($longest));
say $longest;  # bbbbbbbbbbbbbbb
say $len;     # 15

$longest = $list[0];
$len = length $longest;
for my $str (@list) {
    if ( length($str) > $len ) {
        $longest = $str;
        $len = length($str);
    }
}
say $longest; # bbbbbbbbbbbbbbb
say $len;     # 15

当使用 Perl 5.13.4 在 MacOS X (10.6.5) 上运行时,我得到的输出是:

<<>>/<<__BE>> : 0 : 4
<<__BE>>/<<>> : 0 : 0
<<>>/<<bb>> : 0 : 2
<<bb>>/<<bbbbbbbbbbbbbbb>> : 0 : 15
<<bbbbbbbbbbbbbbb>>/<<>> : 0 : 0
<<>>/<<aaaaaa>> : 0 : 6
aaaaaa
6
bbbbbbbbbbbbbbb
15
bbbbbbbbbbbbbbb
15

从所有情况来看,第一个reduce的第一个参数始终是零长度字符串,即使在它包含一些数据的奇怪情况下也是如此。

如果删除 'use open ':encoding(UTF-8)';' 行,则其行为正常。

<<>>/<<__BE>> : 0 : 4
<<__BE>>/<<>> : 4 : 0
<<__BE>>/<<bb>> : 4 : 2
<<__BE>>/<<bbbbbbbbbbbbbbb>> : 4 : 15
<<bbbbbbbbbbbbbbb>>/<<>> : 15 : 0
<<bbbbbbbbbbbbbbb>>/<<aaaaaa>> : 15 : 6
bbbbbbbbbbbbbbb
15
bbbbbbbbbbbbbbb
15
bbbbbbbbbbbbbbb
15

这可能表明该错误存在于文件 I/O、UTF-8 编码和 List::Util 交互中的某个位置。另一方面,它可能在更隐蔽的地方。但我的印象是,您有一个可重现的测试用例,并且可以在 Perl 及其核心模块中的某个位置报告为可能的错误。

关于perl - List::Util - 减少 - 长度 - 编码 - 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4238858/

相关文章:

perl - 为什么 perl 不能显示所有类型的 UTF8 字符

Perl 食谱 — 在字符串中插入函数

java - 如何创建(然后获取元素)列表的数组/列表?

css - 向右浮动中间列表项

iphone - 来自编码未知的文本文件的 NSString

perl - 如何在 Mojolicious 应用程序中从命令行获取凭据?

perl - 我可以将 Strawberry Perl 嵌入到 VC++ 6.0 编译的应用程序中,或者在编译器不匹配的情况下使用 Inline::C 吗?

c# - 无法将 void 转换为列表

java - Java中字节流转字符流

python - 从字符串中删除格式