[Moscow.pm] кодировка в Perl почему все это так странно работает?

Илья Винокуров ilvin на mail.ru
Вт Сен 23 02:15:17 PDT 2014


 Здравствуйте, Николай!

Вы используете Console::Locale.
Почитайте документацию  https://metacpan.org/pod/Encode::Locale
Из нее вы поймете, что этот модуль определяет кодировку консоли
более точно, чем детекторы.

Если для STDIN, STDERR, STDOUT вы сделали телодвижения по
автоматической перекодировке, то для @ARGV ничего не сделано,
поэтому разумно использовать:

my $lang = decode( locale =>  $ARGV [0]);

А детекторы кодировок - это зло, существующее из-за безнадеги...

С почтением,
  Илья Винокуров.


Mon, 22 Sep 2014 23:58:07 +0400 от Nikolay Mishin <mi на ya.ru>:
>Илья, привет , удалил Text::Iconv
>-my $converter = Text::Iconv->new( "cp1251", "utf-8");
>-$lang = $converter->convert($lang);
>+Encode::from_to($lang, 'windows-1251', 'utf-8');
>https://github.com/mishin/presentation/commit/2d1ba8adcfc451d45454490b5bf442f95bd41e0a
>и все заработало,
>правда получается, что кодировка , которую Encode::Detect::Detector
>определяет как ISO-8859-7 является одновременно и кодировкой windows-1251,
>странно, что больше этого нигде не написано, в общем парадоксальное решение,
>чисто перебором
>
>22.09.2014, 12:51, "Илья Винокуров" < ilvin на mail.ru >:
>>  Здравствуйте, Николай.
>>
>>  Внутри Perl строки хранятся в кодировке, совместимой с UTF-8. Эта кодировка называется utf8.
>>  Когда строки вводятся в Perl, их нужно декодировать из различных кодировок в utf8.
>>  В том числе нужно декодировать UTF-8 в utf8.
>>  Если строку нужно вывести из Perl, то эту строку нужно кодировать в различные кодировки.
>>  В том числе нужно кодировать utf8 в UTF-8
>>
>>  Этим занимаются функции Encode::encode('UTF-8', $string) и Encode::decode('UTF-8', $string).
>>
>>  Text::Iconv - не используйте это, если точно не знаете почему вам нужен именно этот модуль.
>>
>>  Концепцию работы с кодировками в Perl я рассказал,
>>  а вот свой скрипт поправить потрудитесь сами пожалуйста...
>>
>>  PS: Чтобы не возиться в явном виде с перекодированием строк, в перл используют
>>
>>  binmode STDIN, ":encoding(console_in)" if -t STDIN; binmode STDOUT, ":encoding(console_out)" if -t STDOUT; binmode STDERR, ":encoding(console_out)" if -t STDERR;
>>  После этого в STDIN/STDOUT можно читать/писать строки в кодировке utf8 без перекодирования...
>>
>>  С почтением,
>>    Илья Винокуров.
>>
>>  Mon, 22 Sep 2014 01:28:15 +0400 от Nikolay Mishin < mi на ya.ru >:
>>>  Привет, MoscowPM,
>>>  тут родился вопрос под win7 (юникс могут быть теже странности, не проверял)
>>>
>>>  #!/usr/bin/env perl
>>>  use utf8;
>>>  use Modern::Perl;
>>>  use Encode::Locale;
>>>  use Encode qw( decode encode from_to);
>>>  use Text::Iconv;
>>>  use Encode::Detect::Detector;
>>>  use Data::Dumper qw( Dumper );
>>>
>>>  if (-t)
>>>  {
>>>      binmode(STDIN, ":encoding(console_in)");
>>>  binmode(STDOUT, ":encoding(console_out)");
>>>  binmode(STDERR, ":encoding(console_out)");
>>>  }
>>>
>>>  my $lang = shift or die "Usage: $0 What_is_your_language?\n";
>>>  my_dump('lang_01',$lang);
>>>  my $converter = Text::Iconv->new( "cp1251", "utf-8");
>>>  $lang = $converter->convert($lang);
>>>  my_dump('lang_02',$lang);
>>>  $lang = Encode::decode("utf8",$lang);
>>>  my_dump('lang_03',$lang);
>>>  my_dump('lang_04_перл',qq{перл});
>>>
>>>   $lang =~ /(perl|перл) (?{print "use Perl or die!!\nИспользуй Перл или умри!!";}) /ix;#русский не мачится, почему?
>>>
>>>   sub my_dump
>>>   {
>>>   my ($name,$var)=@_;
>>>   local $Data::Dumper::Useqq = 1;
>>>   local $Data::Dumper::Indent = 0;
>>>   local $Data::Dumper::Terse = 1;
>>>   print(Encode::Detect::Detector::detect(qq{$lang})." ".qq{\$$name }." dump=".Dumper($var)."\n");
>>>   }
>>>
>>>  этот же код на гитхабе
>>>  https://github.com/mishin/presentation/blob/master/100_regex_4_moscow_pm.pl
>>>
>>>  моя задача была, чтобы скрипт
>>>  perl 100_regex_4_moscow_pm.pl перл
>>>  читая из консоли слово "перл" находил его в регексе внутри скрипта
>>>
>>>  вопросы:
>>>  1) почему, если в консоле
>>>  perl -MEncode::Detect::Detector -E "say Encode::Detect::Detector::detect(qq{перл})"
>>>  у меня кодировка ISO-8859-7
>>>  my $converter = Text::Iconv->new( "cp1251", "utf-8");
>>>  Text::Iconv ее проглатывает как cp1251 (причем ISO там не проходит) ?
>>>
>>>  2)что происходит со строкой здесь
>>>  UTF-8 $lang_02 dump="\320\277\320\265\321\200\320\273"
>>>  $lang = Encode::decode("utf8",$lang);
>>>  UTF-8 $lang_03 dump="\x{43f}\x{435}\x{440}\x{43b}"
>>>  --что такое делает decode?
>>>  я так понимаю - он починивает utf8, но что конкретно
>>>
>>>  спасибо, хорошей недели!!
>>>
>>>  --
>>>  С уважением
>>>  Николай Мишин
>>>
>>>  --
>>>  Moscow.pm mailing list
>>>  moscow-pm на pm.org |  http://moscow.pm.org
>>  ,
>>
>>  --
>>  Moscow.pm mailing list
>>  moscow-pm на pm.org |  http://moscow.pm.org
>
>-- 
>С уважением
>Николай Мишин
>-- 
>Moscow.pm mailing list
>moscow-pm на pm.org |  http://moscow.pm.org
>

----------- следущая часть -----------
Вложение в формате HTML было извлечено…
URL: <http://mail.pm.org/pipermail/moscow-pm/attachments/20140923/95d8d3ab/attachment.html>


Подробная информация о списке рассылки Moscow-pm