如何使用YAML更新已经实例化的Ruby对象?

时间:2010-11-10 17:52:23

标签: ruby yaml

基本上,我已经有一个Ruby对象的实例,但是想要更新我可以从yaml获得的任何实例变量。有一个to_yaml函数将我的对象转储到yaml。我正在寻找相反的东西。例如,my_obj.from_yaml(yaml_stuff)并让它更新传入的yaml中的实例变量。

我需要在我的from_yaml函数中使用YAML :: load并复制每个实例变量吗?如果是这种情况,是否有一个函数可以用来快速复制这些变量而不需要打字?

Ruby的yaml库是否已经有了我可以将对象和yaml传递给它的东西,它只会做我想要它做的事情?

为了清晰起见进行编辑

这是一个简单的对象,它将存储和加载非常简单的yaml兼容类型,如字符串和整数。

我最终做了什么

虽然我回答了这个问题,但我想添加我最终做的事情,我的对象猴子补丁

class Object

  def from_yaml(yml)

    if (yml.nil?)
      return
    end

    yml.instance_variables.each do |iv|
      if (self.instance_variable_defined?(iv))
        self.instance_variable_set(iv, yml.instance_variable_get(iv))
      end
    end

  end
end

3 个答案:

答案 0 :(得分:1)

据我所知,YAML图书馆本身并没有这样的内容;它主要用于转储和读取数据,而不是在内存和磁盘上保持最新。如果您计划将数据保存在内存中并且磁盘上的数据同步最少,那么您是否考虑过ActiveRecordStone等数据持久性库?

如果您仍然热衷于使用YAML库,并假设您没有许多不同的类可以持久化,那么简单地编写一个小的“更新程序”方法来更新该类的对象可能是有意义的。类似的对象。或者您可以重新编写应用程序,以确保只需从YAML重新加载所有对象而无需更新它们(即转储旧对象并创建新对象)。

另一种选择是使用元编程来读取对象的属性并相应地更新它们,但这似乎容易出错并且很危险。

答案 1 :(得分:1)

你的问题不够明确。你在说什么课?什么样的YAML文件?您不能将所有序列化到YAML中。

假设您的对象只有一组简单的YAML兼容类型的实例变量,例如字符串,数字和符号。

在这种情况下,您通常可以编写from_yaml方法,将YAML文件加载到key->value对的哈希值中,迭代它并更新名为key的每个实例变量value。这看起来是否有用,如果确实如此,您是否需要帮助编写此类方法?

编辑:

您无需将对象状态保留在哈希中 - 您仍然可以使用ivars和attr_accessors - 只需打开一个新模块(比如YamlUpdateable),实现一个可以更新您的ivars的from_yaml方法来自从YAML反序列化的哈希,并将模块包含在您想要从YAML反序列化的任何类中。

答案 2 :(得分:-1)

您正在寻找的是merge命令。

// fetch yaml file
yml = YAML.load_file("path/to/file.yml")

// merge variables
my_obj.merge(yml)