开发者

How can I update an already instantiated Ruby object with YAML?

开发者 https://www.devze.com 2023-01-24 16:19 出处:网络
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 so

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_y开发者_JAVA百科aml(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


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.


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.


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)
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号