在 Ruby 的 JSON 库中何时使用 dump、generate、to_json 以及 load 和 parse?

问题描述 投票:0回答:1

david4dev 对 this Question 的回答声称,使用

json
库可以使用三种等效方法将对象转换为 JSON 字符串:

JSON.dump(object)
JSON.generate(object)
object.to_json

以及将 JSON 字符串转换为对象的两种等效方法:

JSON.load(string)
JSON.parse(string)

但是看源代码,它们每个似乎都有很大不同,并且它们之间存在一些差异(例如,1)。

它们之间有什么区别?什么时候用哪个?

ruby json
1个回答
29
投票

TL;博士:

总体来说:

  • 使用
    to_json
    (或等效的
    JSON::generate
    )。
  • 使用
    JSON::parse

对于某些特殊用例,您可能需要

dump
load
,但在不是您自己创建的数据上使用
load
是不安全的。


扩展说明:

JSON::dump
vs
JSON::generate

作为其参数签名的一部分,

JSON::generate
允许您设置缩进级别和空白细节等选项。另一方面,
JSON::dump
在其内部调用
::generate
,并具有特定的预设选项,因此您无法自行设置这些选项。

根据文档,

JSON::dump
旨在成为
Marshal::dump
实施方案的一部分。您想要自己显式使用
::dump
的主要原因是您将要传输 JSON 数据(例如通过套接字),因为
::dump
允许您传递类似 IO 的对象作为第二个参数。不幸的是,生成的 JSON 数据并没有像生成时那样真正进行流式传输;它是集体创建的,并且仅在 JSON 完全创建后才发送。这使得 IO 参数仅在微不足道的情况下有用。 两者之间的最后一个区别是

::dump

还可以接受

limit
参数,当超出一定的嵌套深度时,它会引发 ArgumentError。


比较

#to_json

#to_json

接受选项作为参数,因此

JSON::generate(foo, opts)
foo.to_json(opts)
基本上是等价的。内部实现不同,这可能会导致令人惊讶的效果(请参阅评论)。


JSON::load

vs
JSON::parse
类似于 

::dump

在内部调用

::generate
::load
在内部调用
::parse
::load
,与
::dump
一样,也可能采用 IO 对象,但同样,源是一次性读取的,因此流仅限于简单的情况。然而,与
::dump
/
::generate
对偶不同,
::load
::parse
都接受选项作为其参数签名的一部分。

::load

也可以传递一个 proc,它将在从数据解析的每个 Ruby 对象上调用;它还附带一个警告,即

::load
只能与可信数据一起使用。
::parse
没有这样的限制,因此
JSON::parse
是解析不受信任的数据源(例如用户输入和具有未知内容的文件或流)的正确选择。
    

© www.soinside.com 2019 - 2024. All rights reserved.