david4dev对this question的回答声称有三种等效方法可以使用json
库将对象转换为JSON字符串:
JSON.dump(object)
JSON.generate(object)
object.to_json
以及将JSON字符串转换为对象的两种等效方法:
JSON.load(string)
JSON.parse(string)
但是看一下源代码,它们中的每一个似乎都差异很大,并且它们之间存在一些差异(例如,1)。
他们之间有什么不同?何时使用哪个?
答案 0 :(得分:9)
<强> TL; DR:强>
一般情况下,请使用to_json
或等效的generate
和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
是解析不受信任的数据源(如用户输入和文件或内容未知的流)的正确选择。