【问题标题】:How to upgrade safely from JSON 1 to JSON 2 wrt utf8 strings?如何安全地从 JSON 1 升级到 JSON 2 wrt utf8 字符串?
【发布时间】:2011-10-05 00:25:58
【问题描述】:

我们拥有大量使用 JSON v1 API 的大型代码库:

use JSON;
my $json = objToJson($data);
my $data = jsonToObj($json);

我们想升级到 JSON v2,因此我们可以开始在新代码中使用它,因为我们遇到了其他依赖于 v2 API 的模块。

但是,如果我存储了一个由objToJson() 创建的 utf8 字符串,那么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,但仍然保留 v1 API 以向后兼容现有代码?

【问题讨论】:

  • JSON 不支持重载比较,那些带有== 的行并没有按照你的想法做。它只是比较两个不同引用的内存位置,这总是错误的。您需要查看数组引用的内部。此时您应该使用eq,它是字符串比较运算符。
  • 哎呀,谢谢埃里克。代码已更正(问题仍然存在)。
  • 我的回答有什么遗漏吗?

标签: json perl utf-8


【解决方案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

【讨论】:

  • ikegami - 这确实是我遇到问题的第 3 步。我不知道如何在我们的代码库中将 JSON 1.x 的所有用途转换为 JSON::XS。我真正想要的是升级到 JSON 2.x(因为 cpanm 一直在尝试为我做这件事 :))但仍然使用旧的 API,因为它存在
  • 通过转换每次使用来做到这一点,一次一个。
  • 如果我知道 JSON::XS 中 JSON::jsonToObj($encoded) 的等价物是什么,我会使用它!但正如我在上面所指出的,当涉及到 utf8 编码的字符串时,JSON::XS::decode_json 的行为与 JSON::jsonToObj 不同。
  • JSON 会为您返回什么? (使用{ local $Data::Dumper::Useqq = 1; local $Data::Dumper::Terse = 1; print(Dumper($encoded)); print(Dumper(JSON::jsonToObj($encoded))); })
  • "[\"\\u263ab\"]" [ "\342\230\272b" ]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-12
  • 2011-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-07
相关资源
最近更新 更多