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

时间:2022-04-05 22:28:43

david4dev's answer to this question claims that there are three equivalent ways to convert an object to a JSON string using the json library:

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

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

and two equivalent ways to convert a JSON string to an object:

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

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

But looking at the source code, each of them seems to be pretty much different, and there are some differences between them (e.g., 1).

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

What are the differences among them? When to use which?

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

1 个解决方案

#1


9  

TL;DR:

TL; DR:

In general, use to_json or the equivalent generate, and parse.

通常,使用to_json或等效的generate和parse。

For some special use cases, you may want dump or load, but it's unsafe to use load on data you didn't create yourself.

对于某些特殊用例,您可能需要转储或加载,但对您自己未创建的数据使用加载是不安全的。


Extended Explanation:

扩展说明:

JSON::dump vs JSON::generate

JSON :: dump vs JSON :: generate

As part of its argument signature, JSON::generate allows you to set options such as indent levels and whitespace particulars. JSON::dump, on the other hand, calls ::generate within itself, with specific pre-set options, so you lose the ability to set those yourself.

作为其参数签名的一部分,JSON :: generate允许您设置缩进级别和空白详细信息等选项。另一方面,JSON :: dump在自身内部调用:: generate,具有特定的预设选项,因此您无法自己设置这些选项。

According to the docs, JSON::dump is meant to be part of the Marshal::dump implementation scheme. The main reason you'd want to explicitly use ::dump yourself would be that you are about to stream your JSON data (over a socket for instance), since ::dump allows you to pass an IO-like object as the second argument. Unfortunately, the JSON data being produced is not really streamed as it is produced; it is created en masse and only sent once the JSON is fully created. This makes having an IO argument useful only in trivial cases.

根据文档,JSON :: dump意味着是Marshal :: dump实现方案的一部分。你想要自己显式地使用:: dump的主要原因是你要传输你的JSON数据(例如通过套接字),因为:: dump允许你传递一个类似IO的对象作为第二个参数。不幸的是,生成的JSON数据在生成时并没有真正流式传输;它是集体创建的,只有在完全创建JSON后才会发送。这使得IO参数仅在微不足道的情况下有用。

The final difference between the two is that ::dump can also take a limit argument that causes it to raise an ArgumentError when a certain nesting depth is exceeded.

两者之间的最后一个区别是:: dump还可以采用一个limit参数,当超过某个嵌套深度时,它会引发ArgumentError。


Comparison to #to_json

与#to_json的比较

#to_json accepts options as arguments, so internal implementation aside, JSON::generate(foo, opts) and foo.to_json(opts) are equivalent.

#to_json接受选项作为参数,因此除了内部实现,JSON :: generate(foo,opts)和foo.to_json(opts)是等效的。


JSON::load vs JSON::parse

JSON :: load vs JSON :: parse

Similar to ::dump calling ::generate internally, ::load calls ::parse internally. ::load, like ::dump, may also take an IO object, but again, the source is read all at once, so streaming is limited to trivial cases. However, unlike the ::dump/::generate duality, both ::load and ::parse accept options as part of their argument signatures.

类似于:: dump calling :: generate internal :: :: load calls :: parse inside。 :: load,like :: dump,也可以带一个IO对象,但同样,源是一次性读取的,所以流式传输仅限于普通的情况。但是,与:: dump / :: generate duality不同,:: load和:: parse都接受选项作为其参数签名的一部分。

::load can also be passed a proc, which will be called on every Ruby object parsed from the data; it also comes with a warning that ::load should only be used with trusted data. ::parse has no such restriction, and therefore JSON::parse is the correct choice for parsing untrusted data sources like user inputs and files or streams with unknown contents.

:: load也可以传递一个proc,它将在从数据中解析的每个Ruby对象上调用;它还附带一个警告::: load应该只与可信数据一起使用。 :: parse没有这样的限制,因此JSON :: parse是解析不受信任的数据源(如用户输入和文件或具有未知内容的流)的正确选择。

#1


9  

TL;DR:

TL; DR:

In general, use to_json or the equivalent generate, and parse.

通常,使用to_json或等效的generate和parse。

For some special use cases, you may want dump or load, but it's unsafe to use load on data you didn't create yourself.

对于某些特殊用例,您可能需要转储或加载,但对您自己未创建的数据使用加载是不安全的。


Extended Explanation:

扩展说明:

JSON::dump vs JSON::generate

JSON :: dump vs JSON :: generate

As part of its argument signature, JSON::generate allows you to set options such as indent levels and whitespace particulars. JSON::dump, on the other hand, calls ::generate within itself, with specific pre-set options, so you lose the ability to set those yourself.

作为其参数签名的一部分,JSON :: generate允许您设置缩进级别和空白详细信息等选项。另一方面,JSON :: dump在自身内部调用:: generate,具有特定的预设选项,因此您无法自己设置这些选项。

According to the docs, JSON::dump is meant to be part of the Marshal::dump implementation scheme. The main reason you'd want to explicitly use ::dump yourself would be that you are about to stream your JSON data (over a socket for instance), since ::dump allows you to pass an IO-like object as the second argument. Unfortunately, the JSON data being produced is not really streamed as it is produced; it is created en masse and only sent once the JSON is fully created. This makes having an IO argument useful only in trivial cases.

根据文档,JSON :: dump意味着是Marshal :: dump实现方案的一部分。你想要自己显式地使用:: dump的主要原因是你要传输你的JSON数据(例如通过套接字),因为:: dump允许你传递一个类似IO的对象作为第二个参数。不幸的是,生成的JSON数据在生成时并没有真正流式传输;它是集体创建的,只有在完全创建JSON后才会发送。这使得IO参数仅在微不足道的情况下有用。

The final difference between the two is that ::dump can also take a limit argument that causes it to raise an ArgumentError when a certain nesting depth is exceeded.

两者之间的最后一个区别是:: dump还可以采用一个limit参数,当超过某个嵌套深度时,它会引发ArgumentError。


Comparison to #to_json

与#to_json的比较

#to_json accepts options as arguments, so internal implementation aside, JSON::generate(foo, opts) and foo.to_json(opts) are equivalent.

#to_json接受选项作为参数,因此除了内部实现,JSON :: generate(foo,opts)和foo.to_json(opts)是等效的。


JSON::load vs JSON::parse

JSON :: load vs JSON :: parse

Similar to ::dump calling ::generate internally, ::load calls ::parse internally. ::load, like ::dump, may also take an IO object, but again, the source is read all at once, so streaming is limited to trivial cases. However, unlike the ::dump/::generate duality, both ::load and ::parse accept options as part of their argument signatures.

类似于:: dump calling :: generate internal :: :: load calls :: parse inside。 :: load,like :: dump,也可以带一个IO对象,但同样,源是一次性读取的,所以流式传输仅限于普通的情况。但是,与:: dump / :: generate duality不同,:: load和:: parse都接受选项作为其参数签名的一部分。

::load can also be passed a proc, which will be called on every Ruby object parsed from the data; it also comes with a warning that ::load should only be used with trusted data. ::parse has no such restriction, and therefore JSON::parse is the correct choice for parsing untrusted data sources like user inputs and files or streams with unknown contents.

:: load也可以传递一个proc,它将在从数据中解析的每个Ruby对象上调用;它还附带一个警告::: load应该只与可信数据一起使用。 :: parse没有这样的限制,因此JSON :: parse是解析不受信任的数据源(如用户输入和文件或具有未知内容的流)的正确选择。