Эффект черного ящика

Многие программисты на Perl частенько используют модуль XML::Simple для обработки файлов. Казалось бы, что может быть проще, чем распарсить файл:

use XML::Simple;
my $xs = XML::Simple->new();
my $ref = $xs->XMLin(‘test.xml’);

Однако даже такой простой кусок кода в разных системах реагировал по-разному на один и тот же исходный файл. Если в исходном файле XML встречались символы в кодировке utf8, скрипт мог свалиться на этапе разбора файла.

Выяснилось, что модуль XML::Simple сам по себе не занимается разбором XML, и парсинг происходит с помощью других доступных модулей. Если в системе установлен XML::SAX, то именно он будет использоваться по умолчанию, в противном случае для разбора будет применяться XML::Parser.

С XML::SAX тоже не все просто, он для разбора использует либо XML::SAX::PurePerl (что медленно и не всегда корректно работает), либо XML::SAX::Expat или XML::SAX::ExpatXS (если они установлены).

Так вот, чтобы XML::Simple смог корректно разобрать XML файл со строками в кодировке UTF-8, надо установить XML::SAX::Expat или XML::SAX::ExpatXS. Это совершенно не очевидно, и об этом можно забыть при переносе скриптов с сервера на сервер.