【问题标题】:Ruby deserializing YAMLRuby 反序列化 YAML
【发布时间】:2011-10-16 04:52:19
【问题描述】:

我正在使用 DelayedJob,我需要重写一个我认为在从 YAML 反序列化对象时正在使用的方法:self.yaml_new(在delayed/serialization/active_record 中定义)

我的印象是,当 YAML 反序列化一些数据时,它会在该数据类型的类上调用 yaml_new 方法

DJ 的yaml_new 方法使用传入的 id 从数据库中获取对象

我无法用我自己的课程实现这种行为。当我在类上设置self.yaml_new 方法并尝试在序列化实例上YAML.load 时,它似乎没有调用yaml_new,所以我显然弄错了。

那么这个方法有什么用呢?

搜索yaml_new 并没有什么收获(只是其他人使用它的 API 文档)。所以我想知道这个方法到底是什么。

我认为yaml_new 将是在找到某个类型的对象时调用的某个钩子方法,如果该方法存在于类中。但我又一次无法真正让它发挥作用。下面是一个示例:

class B
  def self.yaml_new(klass, tag, val)
    puts "I'm in yaml new!"
  end
end

b = B.new
YAML.load b.to_yaml    # expected "I'm in yaml new!" got nothing

更新

所以在我的 Rails 应用程序中玩过之后,似乎yaml_new 确实实际上是从YAML.load 调用的。我有一个像这样的文件:

module ActiveRecord
  class Base

    def self.yaml_new(klass, tag, val)
      puts "\n\n yaml_new!!!\n\n"
      klass.find(val['attributes']['id'])
    rescue ActiveRecord::RecordNotFound
      raise Delayed::DeserializationError
    end

    def to_yaml_properties
      ['@attributes', '@database']    # add in database attribute for serialization
    end

  end
end

这正是 DJ 所做的,除了我正在记录动作。

YAML.load Contact.first.to_yaml
# => yaml_new!!!

我实际上得到了记录的输出!!

那么我在 Rails 应用程序之外做错了什么?还有其他方法可以触发此方法吗?我问是因为我试图在我自己的 gem 中测试它,而 yaml_new 方法没有触发,所以我的测试失败了,但它确实在 Rails 中工作

【问题讨论】:

    标签: ruby serialization yaml deserialization


    【解决方案1】:

    你需要添加类似的东西

    yaml_as "tag:ruby.yaml.org,2002:B"
    

    self.yaml_new 方法的定义之前。根据yaml/tag.rb中的cmets,yaml_as:

    在类中添加taguri tag,在转储或加载类时使用 在 YAML 中。请参阅 YAML::tag_class 以获取有关键入和 塔古里斯。

    【讨论】:

      猜你喜欢
      • 2013-08-21
      • 2012-09-09
      • 1970-01-01
      • 1970-01-01
      • 2020-11-06
      • 1970-01-01
      • 2010-12-10
      • 2015-03-16
      • 2017-11-02
      相关资源
      最近更新 更多