我正在尝试将包含嵌套哈希的哈希转换为对象,以便可以使用点语法访问属性(包括嵌套属性)。
到目前为止,第一个哈希对象已被以下代码成功转换:
class Hashit
def initialize(hash)
hash.each do |k,v|
self.instance_variable_set("@#{k}", v)
self.class.send(:define_method, k, proc{self.instance_variable_get("@#{k}")})
self.class.send(:define_method, "#{k}=", proc{|v| self.instance_variable_set("@#{k}", v)})
end
end
end
问题是,这种方法不适用于嵌套哈希:
h = Hashit.new({a: '123r', b: {c: 'sdvs'}})
=> #<Hashit:0x00000006516c78 @a="123r", @b={:c=>"sdvs"}>
请注意,在输出中,@b={:c=>"sdvs"}
没有被转换;它仍然是一个散列。
如何将嵌套哈希转换为对象?
6条答案
按热度按时间zzlelutf1#
您可以使用OpenStruct http://ruby-doc.org/stdlib-2.0.0/libdoc/ostruct/rdoc/OpenStruct.html
uujelgoq2#
另一种方法是使用JSON和OpenStruct,它们是标准的Ruby库:
pdkcd3nj3#
您需要添加递归性:
gudnpqoy4#
Ruby有一个内置的数据结构OpenStruct来解决类似的问题。但是,仍然有一个问题。它不是递归的。所以,你可以像这样扩展OpenStruct类:
下次使用OpenStruct时请记住
require 'open_struct.rb'
。现在您可以执行以下操作:
u59ebvdq5#
当初始化对象时,可以检查
v
上的类型,并在new
是另一个哈希值时调用new
以获取新的Hashit
。而之前的结果片段将是:
23c0lvtd6#
如果我对问题的理解正确的话,这应该可以做到: