【问题标题】:How can I update an already instantiated Ruby object with YAML?如何使用 YAML 更新已经实例化的 Ruby 对象?
【发布时间】:2010-11-10 17:52:23
【问题描述】:

基本上,我已经有一个 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

【问题讨论】:

    标签: ruby yaml


    【解决方案1】:

    你的问题不够清楚。你说的是哪个班?什么样的 YAML 文件?您不能将所有内容序列化到 YAML 和从 YAML 序列化。

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

    在这种情况下,您通常可以编写 from_yaml 方法,该方法会将 YAML 文件加载到 key->value 对的哈希中,遍历它并使用 value 更新每个名为 key 的实例变量。这看起来有用吗?如果有用,你需要帮助编写这样的方法吗?

    编辑:

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

    【讨论】:

    • 对不起,如果我不清楚。对象成员由非常简单的 YAML 兼容类型组成。我不知道这个功能是否已经存在于 ruby​​ 的 yaml 库中,或者我是否需要做一些特别的事情。听起来我需要做一些特别的事情。我可能需要将此作为一个不同的问题发布,但是将实例数据存储在哈希中并使用 method_missing 更新数据是否有优势?然后我可以用 yaml 进出哈希。
    【解决方案2】:

    据我所知,YAML 库本身并没有这样的功能;它主要用于转储和读取数据,而不是在内存和磁盘上保持最新。如果您打算以最小的麻烦将数据保存在内存和磁盘上,那么您是否考虑过像 ActiveRecordStone 这样的数据持久性库?

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

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

    【讨论】:

      【解决方案3】:

      您要查找的是merge 命令。

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

      【讨论】:

      • 对象类上好像没有合并功能。不过哈希类有一个。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-05
      • 1970-01-01
      • 2020-02-20
      • 2013-04-21
      • 1970-01-01
      • 2021-04-12
      相关资源
      最近更新 更多