使用带有Unicode输入的Term :: ReadLine

时间:2015-07-22 20:13:53

标签: perl unicode utf-8 readline

我试图弄清楚如何使用Term::ReadLine从终端读取Unicode输入。事实证明,如果我在提示符处输入Unicode字符,则返回的字符串会因各种设置而异。 (我正在运行Ubuntu 14.10,并已安装Term::ReadLine::Gnu)。例如(p.pl):

use open qw( :std :utf8 );
use strict;
use warnings;

use Devel::Peek;
use Term::ReadLine;

my $term   = Term::ReadLine->new('ProgramName');
$term->ornaments( 0 );
my $ans = $term->readline("Enter message: ");
Dump ( $ans );

在提示符下运行p.pl并输入å会产生输出:

Enter message: å
SV = PV(0x83a5a0) at 0x87c080
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x917500 "\303\245"\0
  CUR = 2
  LEN = 10

因此返回的字符串$ans未设置UTF-8标志。但是,如果我使用perl -CS p.pl运行程序,则输出为:

Enter message: å
SV = PVMG(0x24c12e0) at 0x23050a0
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK,UTF8)
  IV = 0
  NV = 0
  PV = 0x248faf0 "\303\245"\0 [UTF8 "\x{e5}"]
  CUR = 2
  LEN = 10

$ans上正确设置了UTF-8标志。所以第一个问题是:为什么命令行选项-CS与使用编译指示use open qw( :std :utf8 )不同?

接下来,我使用Term::ReadLine::Stub选项测试了-CS

$ PERL_RL=Stub perl -CS p.pl

输出现在是:

Enter message: å
SV = PV(0xf97260) at 0xfd90c8
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK,UTF8)
  PV = 0x10746e0 "\303\203\302\245"\0 [UTF8 "\x{c3}\x{a5}"]
  CUR = 4
  LEN = 10

并且输出字符串$ans已被双重编码,因此输出已损坏。这是一个错误,还是预期的行为?

2 个答案:

答案 0 :(得分:2)

正如Denis Ibaev在answer中解释的那样,问题是Term::ReadLine没有读取STDIN,它会打开一个新的输入文件句柄。作为调用binmode($term->IN, ':utf8')的替代方法,事实证明,通过提供-CS可以使命令行选项use open qw( :std :utf8)Term::ReadLine开箱即用STDIN。 }作为Term::ReadLine->new()的参数,正如在这个问题的答案中所解释的那样:Term::Readline: encoding-question

例如:

use strict;
use utf8;
use open qw( :std :utf8 );
use warnings;
use Term::ReadLine;

my $term   = Term::ReadLine->new('Test', \*STDIN, \*STDOUT);
my $answer = $term->readline( 'Enter input: ' );

答案 1 :(得分:1)

Term::ReadLine未读取STDINopens new文件句柄。所以use open qw(:std :utf8);没有效果。

你需要做这样的事情:

my $term = Term::ReadLine->new('name');
binmode($term->IN, ':utf8');

关于-CS的更新:

选项-C为魔术变量${^UNICODE}设置了一些值。 -CS(或-CI)选项使表达式${^UNICODE} & 0x0001成立。如果Term::ReadLine为真,则输入字符串为${^UNICODE} & 0x0001 sets UTF-8 flag on

注意,选项-CSbinmode($term->IN, ':utf8')不同。第一个只设置UTF-8标志,第二个设置字符串。