Ruby 反序列化 YAML

发布于 2024-11-27 07:06:36 字数 1527 浏览 1 评论 0原文

我正在使用 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 调用的。加载。我在那里有一个文件,如下所示:

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 中工作

I'm working with DelayedJob and I need to override a method that I thought was being used when an object is deserialized from YAML: self.yaml_new (defined in in delayed/serialization/active_record)

My impression was that when YAML deserialized some data, it would call the yaml_new method on the class of the type of that data

DJ's yaml_new method fetches the object from the database using the passed in id

I'm unable to achieve this behaviour with my own classes. When I set a self.yaml_new method on a class and try to YAML.load on a serialized instance, it doesn't seem to call yaml_new so I must obviously be mistaken.

What then is this method for?

Searching for yaml_new doesn't yield much (just API docs of other people using it). So I'm wondering what exactly this method is.

I figured yaml_new would be some hook method called when an object is found of some type if that method existed on the class. But again I can't actually get this to work. Below is a sample:

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

updates

So after playing around in my Rails application, it appears that yaml_new does actually get called from YAML.load. I have a file in there like so:

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

Which is just what DJ does, except I'm logging the action.

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

I actually get the logged output!!

So what am I doing wrong outside of my Rails app?? Is there some other way of getting this method to trigger?? I ask because I'm trying to test this in my own gem and the yaml_new method doesn't trigger, so my tests fail, and yet it actually does work inside Rails

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

箜明 2024-12-04 07:06:36

您需要

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

在 self.yaml_new 方法的定义之前添加类似的内容。根据yaml/tag.rb中的注释,yaml_as:

向类添加 taguri 标签,在转储或加载类时使用
在 YAML 中。有关键入和的详细信息,请参阅 YAML::tag_class
塔古里斯。

You need to add something like

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

before the definition of the self.yaml_new method. According to the comments in yaml/tag.rb, yaml_as:

Adds a taguri tag to a class, used when dumping or loading the class
in YAML. See YAML::tag_class for detailed information on typing and
taguris.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文