obj.my_json_property
,即满足原始要求),请使用以下方法:require 'json'
obj = JSON.parse(json_text, object_class: OpenStruct)
puts obj.my_json_property
object_class: Struct
,但是它会出现"TypeError: allocator undefined for Struct"的错误。然而,对于大多数(但不是全部)实际目的而言,OpenStruct完全可以胜任。其主要缺点是,如果您拼错了某个属性名称,则您的代码仍将正常运行,该值将只是nil/空字符串(具体取决于上下文)......这可能有点令人恼火和误导。Hash#[]
与Hash#fetch
之间的区别(有关参考,请参见:http://devblog.avdi.org/2009/03/16/go-fetch/)。Hash
转换为Struct
的相对快速的方法: class Hash
def to_struct
s = Struct.new(*self.keys.map(&:to_sym))
construct = map do |k,v|
v.is_a?(Hash) ? v.to_struct : v.is_a?(Array) ? v.join(", ") : v
end
s.new(*construct)
end
end
。
h = {hello: 'world',foo: {bar: 'baz'}}
m = h.to_struct
#=> #<struct hello="world", foo=#<struct bar="baz">>
m.hello
#=> "world"
m.foo
#=> #<struct bar="baz">
m.foo.bar
#=> "baz"
require 'json'
obj = JSON.parse(json_text).to_struct
这将能够正常工作并且也能处理嵌套对象(需要一些明显的处理,针对 Array
*我没有关注这部分,因为它不是问题的一部分)。
Struct.new
创建一个具有所需访问器的新类,您可以将其作为object_class
传递给JSON.parse
:> require 'json'
> MyStruct = Struct.new(:my_json_property)
> obj = JSON.parse('{"my_json_property": "foo"}', object_class: MyStruct)
=> #<struct my_json_property="foo">
> obj.my_json_property
=> "foo"
Hash
在数据访问方面比OpenStruct
快得多。 - engineersmnkyHash
是一个真正的对象,但每个人都有自己的喜好。如果你真的想要一个Struct
,不妨试试我的答案。 - engineersmnkyHash#[]
或Hash#fetch
来检索内容。 - Per Lundberg