Iterate and Set Ruby Object Instance Variables

喜你入骨 提交于 2019-12-02 19:06:29

问题


I'm looking for a way to iterate through a Ruby object's instance variables, and set them individually (from a provided hash) using a generic setter. I am assuming I can iterate through them directly in a method and simply set each individually.

Here is my object instance, u:

u = #<Waffle:0x00007fc6b1145530 
    @id=nil,
    @alpha="",
    @bravo="",
    @charlie="",
    @delta=nil,
    @echo=nil,
    @status=new>

I would like to populate it with a given hash, h:

h = {
    "id"=>"141",
     "alpha"=>"Muccahiya""
     "bravo"=>"$2a$10$xR2g",
     "charlie"=>"2018-02-21 10:41:56-05",
     "delta"=>"2018-02-05 18:17:16.752606-05",
     "echo"=>"wobbly",
     "status"=>"active"
}

This is the method I have and it is throwing this error:

def to_obj(h)
    self.instance_variables.each do |i|
        self.i = h[i.sub('@','')]
    end
end

Error:

Traceback (most recent call last):
3: from /users/rich/app.rb:31:in `<main>'
2: from /Library/WebServer/Documents/dingbat/models/waffle.rb:240:in `to_obj'
1: from /Library/WebServer/Documents/dingbat/models/waffle.rb:240:in `each'
/Library/WebServer/Documents/dingbat/models/waffle.rb:241:in `block in to_obj': no implicit conversion of String into Integer (TypeError)

self.instance_variables is indeed an array of symbols.

I am thinking that an object can set its instance_variables given a hash. This can't be difficult.


回答1:


def to_obj(h)
  h.each{|k, v| instance_variable_set("@{k}", v)}
end

If you want to set a value only if such instance variable is defined, then do:

def to_obj(h)
  h.each do
    |k, v|
    next unless instance_variable_defined?("@{k}")
    instance_variable_set("@{k}", v)
  end
end


来源:https://stackoverflow.com/questions/48681379/iterate-and-set-ruby-object-instance-variables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!