Ruby 反序列化 YAML
我正在使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要
在 self.yaml_new 方法的定义之前添加类似的内容。根据yaml/tag.rb中的注释,yaml_as:
You need to add something like
before the definition of the
self.yaml_new
method. According to the comments in yaml/tag.rb, yaml_as: