#json #perl #utf-8
#json #perl #utf-8
Вопрос:
У нас большая база кода, которая широко использует API JSON v1:
use JSON;
my $json = objToJson($data);
my $data = jsonToObj($json);
Мы хотели бы перейти на JSON v2, чтобы начать использовать его в новом коде, а также потому, что мы сталкивались с другими модулями, которые зависят от API v2.
Однако, если я сохранил строку utf8, созданную objToJson()
, она больше не будет декодироваться таким же образом с помощью JSON::XS (именно это JSON v2 использует за кулисами).
use JSON;
use JSON::XS;
use warnings;
use strict;
my $data = ["x{263a}b"];
my $encoded = JSON::objToJson($data);
print "different!n"
unless JSON::jsonToObj($encoded)->[0] eq JSON::XS::decode_json($encoded)->[0];
print "different!n"
unless JSON::jsonToObj($encoded)->[0] eq JSON::XS->new->decode($encoded)->[0];
Есть ли у нас какой-либо способ перейти на JSON v2, но при этом оставить API v1 для обратной совместимости с существующим кодом?
Комментарии:
1. JSON не поддерживает перегруженное сравнение, и эти строки с
==
делают не то, что вы думаете. Это просто сравнение позиций памяти двух разных ссылок, которые всегда будут ложными. Вам нужно заглянуть внутрь ссылок на массив. И в этот момент вы должны использоватьeq
which является оператором сравнения строк.2. Упс, спасибо, Эрик. Исправлен код (проблема остается той же).
3. В моем ответе чего-то не хватает?
Ответ №1:
Модули должны использовать новое имя, когда они вносят подобные радикальные изменения. В этом случае тот факт, что JSON 2.x в основном является оболочкой для JSON::XS, удобно означает, что это то, что они сделали.
Я рекомендую:
- Оставьте JSON 1.x установленным.
- Установите JSON::XS.
- На досуге конвертируйте из JSON 1.x в JSON::XS.
- Теперь можно безопасно перейти на JSON 2.x, если хотите.
- Установите JSON 2.x
- s / JSON::XS/JSON /g
Комментарии:
1. ikegami — у меня действительно проблема с шагом 3. Я не знаю, как преобразовать все варианты использования JSON 1.x в JSON::XS в нашей кодовой базе. Чего я действительно хочу, так это перейти на JSON 2.x (поскольку cpanm продолжает пытаться сделать это для меня :)), но по-прежнему использовать старый API в том виде, в каком он существует
2. Сделайте это, преобразуя каждое использование по одному за раз.
3. Если бы я знал, что такое эквивалент JSON::jsonToObj($encoded) в JSON::XS, я бы использовал его! Но, как я указывал выше, JSON ::XS::decode_json ведет себя иначе, чем JSON ::jsonToObj, когда дело доходит до строк в кодировке utf8.
4. Что возвращает вам JSON? (использовать
{ local $Data::Dumper::Useqq = 1; local $Data::Dumper::Terse = 1; print(Dumper($encoded)); print(Dumper(JSON::jsonToObj($encoded))); }
)5. «[» \ u263ab»]» [ «342230 272b» ]