Как может я правильно переменные условий применения, закодированные как Windows 1251 в Perl?

Мне установили переменную среды в Windows как TEST=abc£ который использует Windows-1252 кодовая страница. Теперь, когда я запускаю программу Perl test.pl это значение среды прибывает правильно.

Когда я называю другой код Perl - test2.pl от test1.pl любой system(..) или Win32::Process, среда прибывает искаженная.

Кто-то может предоставить информацию, почему это могло быть и способ разрешить его?

Версия perl Я использую, 5.8.

Если мое понимание является правильным, perl внутренне использование utf-8, так начальный процесс - test1.pl полученный это прямо из Windows-1252utf-8. Когда мы назовем другой процесс, должны мы преобразовывать назад в Windows-1252 кодовая страница?

6
задан brian d foy 17 March 2010 в 03:05
поделиться

1 ответ

Это не имеет отношения к внутренней кодировке строк Perl, а связано с необходимостью правильно декодировать данные, поступающие извне. Я предоставлю тестовый пример. Это Strawberry Perl 5.10 на западноевропейской Windows XP.

test1.pl:

use Devel::Peek;
print Dump $ENV{TEST};
use Encode qw(decode);
my $var = decode 'Windows-1252', $ENV{TEST};
print Dump $var;

system "B:/sperl/perl/bin/perl.exe B:/test2.pl";

test2.pl:

use Devel::Peek;
print Dump $ENV{TEST};
use Encode qw(decode);
my $var = decode 'IBM850', $ENV{TEST};
# using Windows-1252 again is wrong here
print Dump $var;

Execute:

> set TEST=abc£
> B:\sperl\perl\bin\perl.exe B:\test1.pl

Output (shortened):

SV = PVMG(0x982314) at 0x989a24
  FLAGS = (SMG, RMG, POK, pPOK)
  PV = 0x98de0c "abc\243"\0
SV = PV(0x3d6a64) at 0x989b04
  FLAGS = (PADMY, POK, pPOK, UTF8)
  PV = 0x9b5be4 "abc\302\243"\0 [UTF8 "abc\x{a3}"]
SV = PVMG(0x982314) at 0x989a24
  FLAGS = (SMG, RMG, POK, pPOK)
  PV = 0x98de0c "abc\243"\0
SV = PV(0x3d6a4c) at 0x989b04
  FLAGS = (PADMY, POK, pPOK, UTF8)
  PV = 0x9b587c "abc\302\243"\0 [UTF8 "abc\x{a3}"]

Вы укушены тем, что Windows использует другую кодировку для текстовой среды (IBM850), чем для графической (Windows-1252). Эксперт должен объяснить более глубокие детали этого явления.

Edit:

Можно эвристически (то есть иногда это не даст нужного результата, особенно для таких коротких строк) определить кодировки. Лучшим решением общего назначения является Encode::Detect/Encode::Detect::Detector, который основан на Mozilla nsUniversalDetector.

Существуют некоторые способы неявного декодирования внешних данных, такие как open pragma/IO layers и -C switch, однако они работают только с файловыми потоками и аргументами программы. В настоящее время, из окружения должны быть декодированы явно. В любом случае, мне это больше нравится, явное показывает программисту, занимающемуся сопровождением, что вы продумали тему.

9
ответ дан 10 December 2019 в 02:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: