gpt4 book ai didi

ruby - 如何反序列化来自外部源的 YAML 文档并获得对类成员的完全访问权限?

转载 作者:数据小太阳 更新时间:2023-10-29 07:40:00 25 4
gpt4 key购买 nike

在 Ruby 中,通过将“to_yaml”方法的输出保存到文件中,可以将任何对象传输(即序列化)到 YAML 文档。之后,可以使用 YAML::load 方法再次读取此 YAML 文件,即反序列化。此外,可以完全访问底层类/对象的所有成员。

只要我将 Ruby 用作单一平台,所有这些都是有效的。一旦我在 Java 中序列化对象并在 Ruby 中反序列化它们,由于 NoMethodError 异常,我无法再访问该对象。这是由于对象/本地数据类型在不同系统下的命名方式所致。

给定一个 Ruby 类“Car”:

# A simple class describing a car
#
class Car
attr :brand, :horsepower, :color, :extra_equipment

def initialize(brand, horsepower, color, extra_equipment)
@brand = brand
@horsepower = horsepower
@color = color
@extra_equipment = extra_equipment
end
end

创建一个简单的实例:

# creating new instance of class 'Car' ...
porsche = Car.new("Porsche", 180, "red", ["sun roof", "air conditioning"])

调用 porsche.to_yaml 会产生以下输出:

--- !ruby/object:Car 
brand: Porsche
color: red
extra_equipment:
- sun roof
- air conditioning
horsepower: 180

我通过加载 YAML 输出来测试反序列化:

# reading existing yaml file from file system
sample_car = YAML::load(File.open("sample.yaml"))
puts sample_car.brand # returns "Porsche"

这按预期工作,但现在让我们假设 YAML 文档是由不同的系统生成的并且没有任何对 Ruby 的引用,尽管有一个符合 yaml 的对象描述,“!Car”,而不是"!ruby/object:Car":

--- !Car 
brand: Porsche
color: red
extra_equipment:
- sun roof
- air conditioning
horsepower: 180

这段代码:

# reading existing yaml file from file system
sample_car = YAML::load(File.open("sample.yaml"))
puts sample_car.brand # returns "Porsche"

返回这个异常:

/path/yaml_to_object_converter.rb.rb:27:in `<main>':
undefined method `brand' for #<YAML::DomainType:0x9752bec> (NoMethodError)

有没有办法处理“外部”YAML 文档中定义的对象?

最佳答案

对我来说,IRB shell 中的 sample_car 计算为:

=> #<Syck::DomainType:0x234df80 @domain="yaml.org,2002", @type_id="Car", @value={"brand"=>"Porsche", "color"=>"red", "extra_equipment"=>["sun roof", "air conditioning"], "horsepower"=>180}>

然后我发布了sample_car.value:

=> {"brand"=>"Porsche", "color"=>"red", "extra_equipment"=>["sun roof", "air conditioning"], "horsepower"=>180}

这是一个哈希。这意味着,您可以通过向 Car 添加类方法来构造您的 Car 对象,如下所示:

def self.from_hash(h)
Car.new(h["brand"], h["horsepower"], h["color"], h["extra_equipment"])
end

然后我试了一下:

porsche_clone = Car.from_hash(sample_car.value)

返回的是:

=> #<Car:0x236eef0 @brand="Porsche", @horsepower=180, @color="red", @extra_equipment=["sun roof", "air conditioning"]>

这是最丑陋的做法。可能还有其他人。 =)

编辑(2011 年 5 月 19 日):顺便说一句,刚刚想出更简单的方法:

def from_hash(o,h)
h.each { |k,v|
o.send((k+"=").to_sym, v)
}
o
end

为了在您的情况下起作用,您的构造函数不得需要参数。然后你可以简单地做:

foreign_car = from_hash(Car.new, YAML::load(File.open("foreign_car.yaml")).value)
puts foreign_car.inspect

...这给你:

#<Car:0x2394b70 @brand="Porsche", @color="red", @extra_equipment=["sun roof", "air conditioning"], @horsepower=180>

关于ruby - 如何反序列化来自外部源的 YAML 文档并获得对类成员的完全访问权限?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5966015/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com