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

发布于 2024-10-01 18:54:09 字数 750 浏览 6 评论 0原文

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

Basically, I have an instance of a Ruby object already but want to update whatever instance variables I can from yaml. There is a to_yaml function that will dump my object to yaml. I'm looking for something in the reverse. For example, my_obj.from_yaml(yaml_stuff) and have it update instance variables from the yaml passed in.

Would I need to, in my from_yaml function, use YAML::load and copy each instance variable? Is there a function I can use to quickly copy those variables without much typing if that is the case?

Does Ruby's yaml library have something already where I can pass it the object and the yaml and it'll just do what I want it to do?

Editing for clarity

This is a simple object that will store and load very simple yaml compatible types such as strings and integers.

What I ended up doing

Although I answered this question I wanted to add what I ended up doing, my Object monkey patch

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

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

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

发布评论

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

评论(3

夜夜流光相皎洁 2024-10-08 18:54:09

你的问题不够明确。你说的是哪个班级?什么样的 YAML 文档?您无法将所有内容序列化到 YAML 或从 YAML 序列化。

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

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

编辑:

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

Your question is not clear enough. Which class are you talking about? What kind of YAML documents? You can't have everything serialized to and from YAML.

Let's assume that your object just has a set of instance variables of simple, YAML-compatible types, such as strings, numbers and symbols.

In that case, you can generally, write from_yaml method, which would load YAML file into a hash of key->value pairs, iterate through it and update every instance variable named key with value. Does that seem useful, and if it does, do you need help writing such method?

Edit:

There is no need for you to keep your object state in a hash - you can still use ivars and attr_accessors - just open up a new module (say YamlUpdateable), implement a from_yaml method which would update your ivars from a hash deserialized from YAML, and include the module in whichever class you want to deserialize from YAML.

2024-10-08 18:54:09

据我所知,YAML 库本身没有包含类似的内容;它主要用于转储和读取数据,而不是在内存和磁盘上保持数据最新。如果您打算以最小的麻烦使内存中和磁盘上的数据彼此同步,您是否考虑过像 ActiveRecord 还是 Stone

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

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

As far as I know, there's nothing like that included with the YAML library itself; it's mostly meant for dumping and reading data, not keeping it up-to-date in memory and on disk. If you're planning to keep data in memory and on disk synced with each other with minimal hassle, have you considered a data persistence library like ActiveRecord or Stone?

If you're still keen on using the YAML library, and assuming you don't have many different classes to persist, it might make sense to simply write a small "updater" method that updates an object of that class given a similar object. Or you could rework your application to make sure you can simply reload all the objects from the YAML without having to update them (i.e., dump the old objects and create new ones).

The other option is to use metaprogramming to read into an object's properties and update them accordingly, but that seems error-prone and dangerous.

虚拟世界 2024-10-08 18:54:09

您正在寻找的是merge命令。

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

// merge variables
my_obj.merge(yml)

What you are looking for is the merge command.

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

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