Текущее состояние работы флага UTF8 и функций - это (на мой взгляд) одна из самых больших ошибок в дизайне языка
когда только был внедрён флаг поведение было более корректным, чем сейчас, но позднее кто-то заметил, что
строка с флагом, разбтая посимвольно и дающая массив 1..255 не равна строке без флага, которая при разбитии посимвольно (побайтово) даёт массив 1..255
это не удивительно, т.к внутренний байтовый массив абсолютно разный
лично я считаю, что сделовало сделать одну простую вещь: сказать, что строка с флагом никогда не может равняться строке без флага
благо инструментарий для проверки на флаг уже был.
но было принято другое решение. поведение было названо "The Unicode Bug" и были внесены изменения, которые приводили к равенству таких строк.
после этого стали создаваться сотни реквестов в RT о том, что модуль подвержен "the unicode bug" (мои были в их числе)
длительная переписка с автором этих тикетов не привела ни к чему. мне не удалось убедить его в том, что такое поведение это нонсенс:
$ perl -MDevel::Peek -E '$a = "\N{U+fd}"; $b = "\xfd"; Dump $a; Dump $b; say $a eq $b'
SV = PV(0x7fd2f3806070) at 0x7fd2f382dd48
REFCNT = 1
FLAGS = (POK,IsCOW,pPOK,UTF8)
PV = 0x7fd2f3401b40 "\303\275"\0 [UTF8 "\x{fd}"]
CUR = 2
LEN = 10
COW_REFCNT = 1
SV = PV(0x7fd2f3806120) at 0x7fd2f382dcd0
REFCNT = 1
FLAGS = (POK,IsCOW,pPOK)
PV = 0x7fd2f3401770 "\375"\0
CUR = 1
LEN = 10
COW_REFCNT = 1
1
Поэтому текущая ситуация такая:
- поведение строк в core приведено к duck-typing.
- на флаг UTF8 сказано не обращать внимания (т.е. если вам сказали записать в сокет такую SV'шку,
FLAGS = (POK,IsCOW,pPOK,UTF8) PV = 0x7fd2f3401b40 "\303\275"\0 [UTF8 "\x{fd}"
, вы должны записать один байт 0xFD)
это невероятно печально, но это факт. можно пытаться отрицать, можно принять, но в любом случае нужно знать как оно есть.
есть 2 категории модулей:
1. old-way модули. которые отрицают существование "байтовых строк с флагом". поэтому при наличии флага строка либо энкодится (
"\x{fd}"
->
"\303\275"
), либо бросается exception
2. new-way модули. которые просто разбирают строку по токенам, и если вдруг им нужны байты, а пришёл "символ" с кодом больше 255, бросается исклчение.