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

时间:2014-02-17 08:23:24

标签: ruby json

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

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

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

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

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

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

1 个答案:

答案 0 :(得分:9)

<强> TL; DR:

一般情况下,请使用to_json或等效的generateparse

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