Как безопасно перейти с JSON 1 на JSON 2 с использованием строк utf8?

#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, удобно означает, что это то, что они сделали.

Я рекомендую:

  1. Оставьте JSON 1.x установленным.
  2. Установите JSON::XS.
  3. На досуге конвертируйте из JSON 1.x в JSON::XS.
  4. Теперь можно безопасно перейти на JSON 2.x, если хотите.
    1. Установите JSON 2.x
    2. 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» ]