Ruby YAML :: load

时间:2010-09-16 21:04:16

标签: ruby-on-rails ruby yaml

我正在尝试修改内置时间戳格式的默认反序列化,以影响Ruby的时间。

我使用Hash(成功)执行此操作:

YAML::add_domain_type('yaml.org,2002', 'map') { |t, v| nil }
YAML::add_domain_type('ruby.yaml.org,2002', 'hash') { |t, v| nil }
hash = { :hello => :world }
puts YAML::load(hash.to_yaml) # nil

但是当我尝试使用Time时,它不起作用:

YAML::add_domain_type('yaml.org,2002', 'timestamp') { |t, v| nil }
YAML::add_domain_type('ruby.yaml.org,2002', 'time') { |t, v| nil }
puts YAML::load(Time.now.to_yaml).class # 'Time'

任何帮助将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:2)

如果您使用Psych(在ruby 1.9.3p194中为YAML),则需要在Time类上定义encode_with/1方法。

require 'yaml'

class Time
  def encode_with(coder)
    coder.tag = '!ruby/time'
    coder.scalar = to_s
  end
end

YAML::add_domain_type('ruby.yaml.org,2002', 'ruby/time') { |t, v| "HELLO!!" }

yaml = YAML.dump(Time.new)  # -> "--- !ruby/time 2012-10-25 14:18:59 -0400\n...\n"
YAML.load(yaml)  # -> "HELLO!!"

如果在对象上定义了encode_with/1方法,那么Psych会调用该方法传递Psych::Coder类的实例;否则,它会调用visit_#{o.class}类中的YAMLTree方法,在visit_Time的情况下,该方法不会序列化任何标记信息。

https://github.com/tenderlove/psych/blob/master/lib/psych/visitors/yaml_tree.rb#l100-105

https://github.com/tenderlove/psych/blob/master/lib/psych/visitors/yaml_tree.rb#l172-175