2012-06-28 42 views
3

我試圖從持續對象(從ruby-duration gem)轉儲到自定義類型的yaml,因此它們以hh:mm:ss的形式表示。我試圖修改this question的答案,但是當用YAML.load解析yaml時,會返回Fixnum而不是Duration。有趣的是,Fixnum是持續時間內的總秒數,因此解析似乎可行,但在此之後轉換爲Fixnum。Ruby yaml自定義域名類型不保留類

到目前爲止我的代碼:

class Duration 
    def to_yaml_type 
    "!example.com,2012-06-28/duration" 
    end 

    def to_yaml(opts = {}) 
    YAML.quick_emit(nil, opts) { |out| 
     out.scalar(to_yaml_type, to_string_representation, :plain) 
    } 
    end 

    def to_string_representation 
    format("%h:%m:%s") 
    end 

    def Duration.from_string_representation(string_representation) 
    split = string_representation.split(":") 
    Duration.new(:hours => split[0], :minutes => split[1], :seconds => split[2]) 
    end 
end 

YAML::add_domain_type("example.com,2012-06-28", "duration") do |type, val| 
    Duration.from_string_representation(val) 
end 

爲了澄清,什麼樣的結果我得到:

irb> Duration.new(27500).to_yaml 
=> "--- !example.com,2012-06-28/duration 7:38:20\n...\n" 
irb> YAML.load(Duration.new(27500).to_yaml) 
=> 27500 
# should be <Duration:0xxxxxxx @seconds=20, @total=27500, @weeks=0, @days=0, @hours=7, @minutes=38> 

回答

6

它看起來像你正在使用舊SYCK接口,而該新精極度緊張。除了使用to_yamlYAML.quick_emit,您可以使用encode_with,而不是add_domain_type使用add_taginit_with。 (這方面的文檔很差,我可以提供的最好的文檔是link to the source)。

class Duration 
    def to_yaml_type 
    "tag:example.com,2012-06-28/duration" 
    end 

    def encode_with coder 
    coder.represent_scalar to_yaml_type, to_string_representation 
    end 

    def init_with coder 
    split = coder.scalar.split ":" 
    initialize(:hours => split[0], :minutes => split[1], :seconds => split[2]) 
    end 

    def to_string_representation 
    format("%h:%m:%s") 
    end 

    def Duration.from_string_representation(string_representation) 
    split = string_representation.split(":") 
    Duration.new(:hours => split[0], :minutes => split[1], :seconds => split[2]) 
    end 
end 

YAML.add_tag "tag:example.com,2012-06-28/duration", Duration 

p s = YAML.dump(Duration.new(27500)) 
p YAML.load s 

從這個輸出是:

"--- !<tag:example.com,2012-06-28/duration> 7:38:20\n...\n" 
#<Duration:0x00000100e0e0d8 @seconds=20, @total=27500, @weeks=0, @days=0, @hours=7, @minutes=38> 

(的原因,你所看到的結果是秒的時間總數,因爲它被解析爲sexagesimal integer。)

+0

完美地工作,並感謝解釋,爲什麼我得到了秒。只要我被允許,我會盡快給你賞金 – crater2150