何时在 Ruby 的 JSON 库中使用转储与生成与 to_json 以及加载与解析?
Posted
技术标签:
【中文标题】何时在 Ruby 的 JSON 库中使用转储与生成与 to_json 以及加载与解析?【英文标题】:When to use dump vs. generate vs. to_json and load vs. parse in Ruby's JSON lib? 【发布时间】:2014-03-16 10:46:22 【问题描述】:david4dev 对this question 的回答声称使用json
库可以通过三种等效方法将对象转换为JSON 字符串:
JSON.dump(object)
JSON.generate(object)
object.to_json
以及将 JSON 字符串转换为对象的两种等效方法:
JSON.load(string)
JSON.parse(string)
但是查看源代码,它们每个似乎都有很大的不同,并且它们之间存在一些差异(例如,1)。
它们之间有什么区别?什么时候用哪个?
【问题讨论】:
【参考方案1】:TL;DR:
一般:
使用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
是解析不受信任的数据源(如用户输入和文件或内容未知的流)的正确选择。
【讨论】:
感谢您提供详细信息。解释得很好。以上是关于何时在 Ruby 的 JSON 库中使用转储与生成与 to_json 以及加载与解析?的主要内容,如果未能解决你的问题,请参考以下文章