Я создал OpenStruct
-подобный класс с именем 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
и method_missing
. Полный код .
Я бы хотел предоставить способ настройки строки, сгенерированной to_s
и inspect
. Я хочу сделать так, чтобы пользовательский формат также применялся к вложенным Ribbon
s:
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
объекты являются особым случаем, я подумал, что перехватил бы и обработал их специально:
def to_s(&b)
v = __h__.map do |k, v|
case v
when Ribbon then v.to_s &b
else b ? b.call(k, v) : "#{key}:#{value}"
end
end
"{ Ribbon #{v.join ', '} }"
end
# Now, the keys for all nested hashes but the deepest are hidden.
=> { Ribbon { Ribbon { Ribbon c -> d } }, e -> f }
У меня проблемы с выяснением этого. Как лучше всего решить эту проблему?