我创建了一个名为OpenStruct
的{{1}}类:
Ribbon
不包括:class Ribbon < BasicObject
def __hash__
@hash ||= {}
end
def initialize(hash = {}, &block)
__hash__.merge! hash, &block
Ribbon.convert_all! self
end
def self.convert(object)
case object
when ::Hash then self.new object
when ::Array then object.map { |element| convert element }
else object
end
end
def self.convert_all!(ribbon)
ribbon.__hash__.each do |key, value|
ribbon[key] = case value
when Ribbon then convert_all! value
else convert value
end
end
ribbon
end
end
,[key]
和[key] = value
。 Full code
我想提供一种方法来自定义method_missing
和to_s
生成的字符串。我想这样做,以便自定义格式也适用于嵌套inspect
s:
Ribbon
我的第一次尝试包括以下内容:
hash = { a: { b: { c: 'd' } }, e: 'f' }
ribbon = hash.to_ribbon # Ribbon.new(self)
ribbon.to_s { |k, v| "#{k} -> #{v}" }
=> { Ribbon a -> { Ribbon b -> { Ribbon c -> d } }, e -> f }
由于def to_s(&b)
# __h__ contains the key => value mappings.
v = __h__.map { |k, v| b ? b.call(k, v) : "#{key}:#{value}" }
"{ Ribbon #{v.join ', '} }"
end
# Format is applied only for the receiver.
=> { Ribbon a -> { Ribbon b:{ Ribbon c:d } }, e -> f }
个对象是一个特例,我以为我会拦截并特别处理它们:
Ribbon
我无法搞清楚这一点。解决这个问题的最佳方法是什么?
答案 0 :(得分:2)
试试这个:
def to_s(&b)
v = __h__.map do |k, v|
b ? b.call(k, v.to_s(&b)) : "#{k}: #{v}"
end
"{ Ribbon #{v.join ', '} }"
end
测试:
r = Ribbon.new({a: Ribbon.new({b: Ribbon.new({c: 'd'})}), e: 'f'})
puts r.to_s
=> { Ribbon a: { Ribbon b: { Ribbon c: d } }, e: f }
puts r.to_s {|k, v| "#{k}: #{v}"}
=> { Ribbon a: { Ribbon b: { Ribbon c: d } }, e: f }
puts r.to_s {|k, v| "#{k} => #{v}"}
=> { Ribbon a => { Ribbon b => { Ribbon c => d } }, e => f }