什么时候在Ruby的JSON库中使用dump vs. generate vs. to_json和load与parse?

saw*_*awa 9 ruby json

david4dev对这个问题的回答声称有三种等效方法可以使用该json库将对象转换为JSON字符串:

JSON.dump(object)
JSON.generate(object)
object.to_json
Run Code Online (Sandbox Code Playgroud)

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

JSON.load(string)
JSON.parse(string)
Run Code Online (Sandbox Code Playgroud)

但是看一下源代码,它们中的每一个似乎都差别很大,并且它们之间存在一些差异(例如,1).

他们之间有什么不同?什么时候用哪个?

use*_*951 11

TL; DR:

一般来说,使用to_json或等效generate,和parse.

对于某些特殊用例,您可能需要dumpload,但使用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是解析不受信任的数据源(如用户输入和文件或具有未知内容的流)的正确选择.