2015-05-11 41 views
1

下面的代碼紅寶石陣#to_yaml不叫to_yaml遞歸

require 'yaml' 

class MyObject 
    def initialize(value) 
    @value = value 
    end 

    def to_yaml() 
    @value + @value 
    end 
end 

puts [MyObject.new("a"), MyObject.new("b")] 

生成於紅寶石2.1.3p242以下的輸出:

--- 
- !ruby/object:MyObject 
    value: a 
- !ruby/object:MyObject 
    value: b 

在哪裏我希望它是

--- 
- aa 
- bb 

就好像我在陣列內的每個物體上都調用了to_yaml

puts [MyObject.new("a").to_yaml, MyObject.new("b").to_yaml] 

我在做什麼錯?

回答

0

我更換的Psych::Visitors::YAMLTree

class MyVisitor < Psych::Visitors::YAMLTree 
    def visit_Array o 
    super o.map { |i| i.respond_to?(:to_yaml) ? i.to_yaml : i } 
    end 
end 

visit_Array方法。然後,我傾YAML是這樣的:

a = [MyObject.new("a"), MyObject.new("b")] 
visitor = MyVisitor.create 
visitor << a 
puts visitor.tree.yaml 
1

我離開以前的答案爲好,因爲它可能派上用場,但這是更好的解決方案。

我實際上已經過度簡化了原來的問題。我試圖讓我的自定義對象呈現爲YAML序列[1, 2, 3, ...]。 上一個答案可以用於呈現爲字符串的對象。

這裏的工作版本:

require 'yaml' 

class MyObject 
    def initialize(value) 
    @value = value 
    end 

    def encode_with coder 
    coder.tag = nil 
    coder.seq = [@value, @value] 
    end 
end 

puts [MyObject.new("a"), MyObject.new("b")].to_yaml 

一些參考:

http://blog.mustmodify.com/pages/psych-ruby-1-9-yaml

http://ruby-doc.org/stdlib-1.9.3/libdoc/psych/rdoc/Psych/Coder.html