Ruby 重写OpenStruct的getter以将其作为哈希打印
目标:OpenStruct对象的值应作为哈希而不是对象打印 可能的解决方案:重写OpenStruct类的getterRuby 重写OpenStruct的getter以将其作为哈希打印,ruby,openstruct,Ruby,Openstruct,目标:OpenStruct对象的值应作为哈希而不是对象打印 可能的解决方案:重写OpenStruct类的getter MyOpenStruct覆盖了OpenStruct的new、到和[] class MyOpenStruct < OpenStruct def initialize(object=nil) @table = {} @hash_table = {} if object object.each do
MyOpenStruct
覆盖了OpenStruct的new
、到
和[]
class MyOpenStruct < OpenStruct
def initialize(object=nil)
@table = {}
@hash_table = {}
if object
object.each do |k,v|
if v.is_a?(Array)
other = Array.new()
v.each { |e| other.push(self.class.new(entry)) }
v = other
end
@table[k.to_sym] = (v.is_a?(Hash) ? self.class.new(v) : v)
@hash_table[k.to_sym] = v
new_ostruct_member(k)
end
end
end
def [](val)
@hash_table[val.to_sym]
end
end
只有当我使用[]
访问密钥时,才会返回哈希
如何更正此问题???如果您将其作为散列返回,我认为创建嵌套OpenStruct没有意义。这就是OpenStruct的工作方式:
require 'ostruct'
struct = OpenStruct.new(name: 'first', place: { animal: 'thing' })
struct.place
# => {:animal=>"thing"}
struct.place[:animal]
# => "thing"
struct.place.animal
# => NoMethodError: undefined method `animal' for {:animal=>"thing"}:Hash
因此,如果您想使用点表示法获取struct.place.animal
,您需要像以前一样创建嵌套的OpenStruct对象。
但是,正如我所说,您不需要重写[]
方法。在不重写[]
的情况下使用类,我得到以下结果:
struct = MyOpenStruct.new(name: 'first', place: { animal: 'thing' })
# => #<MyOpenStruct name="first", place=#<MyOpenStruct animal="thing">>
struct.place
# => #<MyOpenStruct animal="thing">
struct.place.animal
# => "thing"
我认为,如果您将其作为散列返回,那么创建嵌套的OpenStruct是没有意义的。这就是OpenStruct的工作方式:
require 'ostruct'
struct = OpenStruct.new(name: 'first', place: { animal: 'thing' })
struct.place
# => {:animal=>"thing"}
struct.place[:animal]
# => "thing"
struct.place.animal
# => NoMethodError: undefined method `animal' for {:animal=>"thing"}:Hash
因此,如果您想使用点表示法获取struct.place.animal
,您需要像以前一样创建嵌套的OpenStruct对象。
但是,正如我所说,您不需要重写[]
方法。在不重写[]
的情况下使用类,我得到以下结果:
struct = MyOpenStruct.new(name: 'first', place: { animal: 'thing' })
# => #<MyOpenStruct name="first", place=#<MyOpenStruct animal="thing">>
struct.place
# => #<MyOpenStruct animal="thing">
struct.place.animal
# => "thing"
我认为,如果您将其作为散列返回,那么创建嵌套的OpenStruct是没有意义的。这就是OpenStruct的工作方式:
require 'ostruct'
struct = OpenStruct.new(name: 'first', place: { animal: 'thing' })
struct.place
# => {:animal=>"thing"}
struct.place[:animal]
# => "thing"
struct.place.animal
# => NoMethodError: undefined method `animal' for {:animal=>"thing"}:Hash
因此,如果您想使用点表示法获取struct.place.animal
,您需要像以前一样创建嵌套的OpenStruct对象。
但是,正如我所说,您不需要重写[]
方法。在不重写[]
的情况下使用类,我得到以下结果:
struct = MyOpenStruct.new(name: 'first', place: { animal: 'thing' })
# => #<MyOpenStruct name="first", place=#<MyOpenStruct animal="thing">>
struct.place
# => #<MyOpenStruct animal="thing">
struct.place.animal
# => "thing"
我认为,如果您将其作为散列返回,那么创建嵌套的OpenStruct是没有意义的。这就是OpenStruct的工作方式:
require 'ostruct'
struct = OpenStruct.new(name: 'first', place: { animal: 'thing' })
struct.place
# => {:animal=>"thing"}
struct.place[:animal]
# => "thing"
struct.place.animal
# => NoMethodError: undefined method `animal' for {:animal=>"thing"}:Hash
因此,如果您想使用点表示法获取struct.place.animal
,您需要像以前一样创建嵌套的OpenStruct对象。
但是,正如我所说,您不需要重写[]
方法。在不重写[]
的情况下使用类,我得到以下结果:
struct = MyOpenStruct.new(name: 'first', place: { animal: 'thing' })
# => #<MyOpenStruct name="first", place=#<MyOpenStruct animal="thing">>
struct.place
# => #<MyOpenStruct animal="thing">
struct.place.animal
# => "thing"
@多吉塔的回答在各方面都是正确的。我只是想回答你的问题“如果这不可能,那么我可以打印整个对象的散列吗temp
?”是的,你可以。您只需将重写为_h
,以递归方式遍历键和值,并将MyOpenStruct实例转换为哈希:
def to_h
@table.each_with_object({}) do |(key, val), table|
table[key] = to_h_convert(val)
end
end
private
def to_h_convert(val)
case val
when self.class
val.to_h
when Hash
val.each_with_object({}) do |(key, val), hsh|
hsh[key] = to_h_convert(val)
end
when Array
val.map {|item| to_h_convert(item) }
else
val
end
end
@多吉塔的回答在各方面都是正确的。我只是想回答你的问题“如果这不可能,那么我可以打印整个对象的散列吗temp
?”是的,你可以。您只需将重写为_h
,以递归方式遍历键和值,并将MyOpenStruct实例转换为哈希:
def to_h
@table.each_with_object({}) do |(key, val), table|
table[key] = to_h_convert(val)
end
end
private
def to_h_convert(val)
case val
when self.class
val.to_h
when Hash
val.each_with_object({}) do |(key, val), hsh|
hsh[key] = to_h_convert(val)
end
when Array
val.map {|item| to_h_convert(item) }
else
val
end
end
@多吉塔的回答在各方面都是正确的。我只是想回答你的问题“如果这不可能,那么我可以打印整个对象的散列吗temp
?”是的,你可以。您只需将重写为_h
,以递归方式遍历键和值,并将MyOpenStruct实例转换为哈希:
def to_h
@table.each_with_object({}) do |(key, val), table|
table[key] = to_h_convert(val)
end
end
private
def to_h_convert(val)
case val
when self.class
val.to_h
when Hash
val.each_with_object({}) do |(key, val), hsh|
hsh[key] = to_h_convert(val)
end
when Array
val.map {|item| to_h_convert(item) }
else
val
end
end
@多吉塔的回答在各方面都是正确的。我只是想回答你的问题“如果这不可能,那么我可以打印整个对象的散列吗temp
?”是的,你可以。您只需将重写为_h
,以递归方式遍历键和值,并将MyOpenStruct实例转换为哈希:
def to_h
@table.each_with_object({}) do |(key, val), table|
table[key] = to_h_convert(val)
end
end
private
def to_h_convert(val)
case val
when self.class
val.to_h
when Hash
val.each_with_object({}) do |(key, val), hsh|
hsh[key] = to_h_convert(val)
end
when Array
val.map {|item| to_h_convert(item) }
else
val
end
end
你的问题不清楚。你的目标是什么?您期望的输出是什么,而您得到的输出是什么?我希望temp.place
返回散列,而不是MyOpenConstruct
对象。凌驾于此无济于事。输入哈希可以比给定的哈希更深。每个访问都应该返回一个散列。如果以散列形式返回,为什么要创建嵌套的OpenStruct?@Doguita如何获得对值的点访问?我的意思是temp.name
和temp[:name]
将不一样。到目前为止,两者都在工作。只是我需要两个人都给我一份temp.name
返回一个对象,但temp[:name]
返回一个哈希值如果希望place
返回不同的值,则需要在子类中重写它。对于name
,同样如此。您的问题不清楚。你的目标是什么?您期望的输出是什么,而您得到的输出是什么?我希望temp.place
返回散列,而不是MyOpenConstruct
对象。凌驾于此无济于事。输入哈希可以比给定的哈希更深。每个访问都应该返回一个散列。如果以散列形式返回,为什么要创建嵌套的OpenStruct?@Doguita如何获得对值的点访问?我的意思是temp.name
和temp[:name]
将不一样。到目前为止,两者都在工作。只是我需要两个人都给我一份temp.name
返回一个对象,但temp[:name]
返回一个哈希值如果希望place
返回不同的值,则需要在子类中重写它。对于name
,同样如此。您的问题不清楚。你的目标是什么?您期望的输出是什么,而您得到的输出是什么?我希望temp.place
返回散列,而不是MyOpenConstruct
对象。凌驾于此无济于事。输入哈希可以比给定的哈希更深。每个访问都应该返回一个散列。如果以散列形式返回,为什么要创建嵌套的OpenStruct?@Doguita如何获得对值的点访问?我的意思是temp.name
和temp[:name]
将不一样。到目前为止,两者都在工作。只是我需要两个人都给我一份temp.name
返回一个对象,但temp[:name]
返回一个哈希值如果希望place
返回不同的值,则需要在子类中重写它。对于name
,同样如此。您的问题不清楚。你的目标是什么?什么是ou