Как я могу заставить Term::Readline установить флаг UTF8 в результатах чтения?

Как заставить Term::Readline установить флаг UTF8 в одном из результатов readline?

#!/usr/local/bin/perl
use warnings FATAL => qw(all);
use strict;
use 5.10.1;
use utf8;
use open qw( :encoding(UTF-8) :std );
use Term::ReadLine;
use Devel::Peek;

my $term = Term::ReadLine->new( 'test', *STDIN, *STDOUT );
$term->ornaments( 0 );
my $char;

$char = $term->readline( 'Enter char: ' );
Dump $char;

print 'Enter char: ';
$char = <>;
chomp $char;
Dump $char;

Выход:

Enter char: ü                                                                                                                                                                                 
SV = PV(0x11ce4c0) at 0x1090078
REFCNT = 1
FLAGS = (PADMY,POK,pPOK)
PV = 0x14552c0 "\374"\0
CUR = 1
LEN = 16
Enter char: ü
SV = PV(0x11ce4c0) at 0x1090078
REFCNT = 1
FLAGS = (PADMY,POK,pPOK,UTF8)
PV = 0x14552c0 "\303\274"\0 [UTF8 "\x{fc}"]
CUR = 2
LEN = 16

Комментарий:

Когда я ищу в базе данных mysql (с включенным mysql_enable_utf8):

my $stmt = "SELECT * FROM $table WHERE City REGEXP ?";
say $stmt;

# my $term = Term::ReadLine->new( 'table_watch', *STDIN, *STDOUT );
# $term->ornaments( 0 ); 
# my $arg = $term->readline( 'Enter argument: ' ); # ü -> doesn't find 'München'

print "Enter argument: ";
my $arg = <>; # ü -> finds 'München'
chomp $arg;

person sid_com    schedule 15.01.2013    source источник


Ответы (1)


Почему? Эти две строки эквивалентны. Это как 0, сохраненный как IV, по сравнению с сохраненным как UV.

Что ж, возможно, вам приходится иметь дело с глючным XS-кодом. Если это так, utf8::upgrade($s) и utf8::downgrade($s) можно использовать для изменения способа хранения строки в скаляре.

В отличие от кодирования и декодирования, utf8::upgrade и utf8::downgrade не изменяют строку, а только то, как она хранится.

$ perl -MDevel::Peek -E'
   $_="\xFC";
   utf8::downgrade($d=$_); Dump($d);
   utf8::upgrade($u=$_);   Dump($u);
   say $d eq $u ?1:0;
'
SV = PV(0x86875c) at 0x4a9214
  REFCNT = 1
  FLAGS = (POK,pPOK)
  PV = 0x8699b4 "\374"\0
  CUR = 1
  LEN = 12
SV = PV(0x868784) at 0x4a8f44
  REFCNT = 1
  FLAGS = (POK,pPOK,UTF8)
  PV = 0x869d14 "\303\274"\0 [UTF8 "\x{fc}"]
  CUR = 2
  LEN = 12
1
person ikegami    schedule 15.01.2013
comment
Я написал комментарий под своим вопросом. - person sid_com; 15.01.2013
comment
Ах да, многие DBD действительно страдают от ошибки Unicode. Предполагая, что Term::ReadLine декодировал, utf8::upgrade определенно то, что вам нужно. - person ikegami; 15.01.2013