gpt4 book ai didi

ruby - 递归地将Ruby对象转储到json

转载 作者:数据小太阳 更新时间:2023-10-29 08:04:06 26 4
gpt4 key购买 nike

我有一个散列需要转储到 json,但其中一个值是一个对象:

hash = { a: my_object }

如果我尝试用 MultiJson.dump(hash) 之类的东西转储它,它只会序列化顶级哈希,而不会更深层次,所以我最终得到的是

'{"a": #<...>}'

即使对象已经有 to_json、to_hash 等方法,并且 MultiJson.dump(my_object) 也会发生这种情况。工作得很好。

这似乎是 JSON 库应该做的事情,但我猜他们不会。为什么不?他们不应该/不能这样做有什么程序上的原因吗?或者我只是错过了什么?

编辑:

再四处搜索一下——我一定是在最初的测试中搞砸了一些东西。 Oj 可以使用 :compat 选项递归地转储 json:

Oj.dump(my_object, mode: :compat)

使用 Oj 的 MultiJson 默认传递这个选项,所以它也可以工作。虽然,根据 Oj 文档,我不确定为什么会这样。即使没有任何 as_hash 或 to_json 方法,它也能正常工作。

最佳答案

通常我会做以下两件事之一:

加载 JSON 的核心扩展:

require 'json/add/core'

我不记得为什么“add/core”对正常的 require 'json' 有帮助,但确实如此。

或者我将 to_hashto_array 方法添加到自定义类,并将它们分解为 Hash 或 Array,然后将其传递给 JSON 类进行序列化。或者我添加一个 to_json 方法并创建一个 Hash 或 Array 然后 to_json 它,返回序列化版本:

class Foo
def initialize
@bar = 1
@baz = [1, 2, 3]
@hub = {'a' => 0, 'b' => 2}
end

def to_h
{
'bar' => @bar,
'baz' => @baz,
'hub' => @hub
}
end

def to_json
to_h.to_json
end
end

require 'json'

Foo.new.to_json # => "{\"bar\":1,\"baz\":[1,2,3],\"hub\":{\"a\":0,\"b\":2}}"

添加代码以对字符串执行 from_json,您可以将对象作为 JSON 发送和接收。或者将该功能添加到您的 initialize 方法中,这样如果它看到参数的字符串,它会尝试将该字符串转换回 Ruby 对象,然后填充值:

class Foo
def initialize(str = nil)
if str && String === str
obj = JSON[str]
@bar, @baz, @hub = obj.values_at('bar', 'baz', 'hub')
else
@bar = 1
@baz = [1, 2, 3]
@hub = {'a' => 0, 'b' => 2}
end
end

def to_h
{
'bar' => @bar,
'baz' => @baz,
'hub' => @hub
}
end

def to_json
to_h.to_json
end
end

require 'json'

json_stream = Foo.new.to_json # !> assigned but unused variable - json_stream
new_foo = Foo.new('{"bar":3,"baz":4,"hub":{"x":8,"y":9}}')
# => #<Foo:0x007f9ed4054d60 @bar=3, @baz=4, @hub={"x"=>8, "y"=>9}>

只要 JSON 知道如何解开一个特定的对象,它就会毫无困难地对其执行 to_json。对于它不知道的那些类型,很容易给它一点帮助。

关于ruby - 递归地将Ruby对象转储到json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25149042/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com