Ruby yaml custom domain type does not keep class -
i'm trying dump duration objects (from ruby-duration gem) yaml custom type, represented in form hh:mm:ss
. i've tried modify answer this question, when parsing yaml yaml.load, fixnum returned instead of duration. interestingly, fixnum total number of seconds in duration, parsing seems work, convert fixnum after that.
my code far:
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") |type, val| duration.from_string_representation(val) end
to clarify, results get:
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 <duration:0xxxxxxx @seconds=20, @total=27500, @weeks=0, @days=0, @hours=7, @minutes=38>
it you’re using older syck interface, rather newer psych. rather using to_yaml
, yaml.quick_emit
, can use encode_with
, , instead of add_domain_type
use add_tag
, init_with
. (the documentation pretty poor, best can offer link 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
the output is:
"--- !<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>
(the reason result you’re seeing total number of seconds in duration because being parsed sexagesimal integer.)
Comments
Post a Comment