具有自定义格式的嵌套结构的递归to_s

时间:2011-12-27 12:20:43

标签: ruby string recursion formatting

我创建了一个名为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] = valueFull code

我想提供一种方法来自定义method_missingto_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

我无法搞清楚这一点。解决这个问题的最佳方法是什么?

1 个答案:

答案 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 }