6

( ruby​​-duration gemから)期間オブジェクトをカスタムタイプでyamlにダンプしようとしているので、フォームで表されhh:mm:ssます。この質問の回答を修正しようとしましたが、YAML.load で yaml を解析すると、Duration ではなく Fixnum が返されます。興味深いことに、Fixnum は期間の合計秒数であるため、解析は機能しているように見えますが、その後 Fixnum に変換されます。

これまでの私のコード:

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>
4

1 に答える 1

10

新しい Psych ではなく、古い Syck インターフェイスを使用しているようです。to_yamlandを使用する代わりに、 and を使用YAML.quick_emitできます。(これに関するドキュメントはかなり貧弱です。私が提供できる最善の方法は、ソースへのリンクです)。encode_withadd_domain_typeadd_taginit_with

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>

(表示されている結果が Duration の合計秒数である理由は、それがsexagesimal integerとして解析されているためです。)

于 2012-12-19T18:11:33.003 に答える