Question

I have a hash of name / value pairs:

attr_hash = {"attr1"=>"val1","attr2=>"val2"}

I want to cycle through each one of these values and assign them to an object like so:

thing = Thing.new
attr_hash.each do |k,v|
  thing.k = v
end

class Thing
   attr_accessor :attr1, :attr2
end

The problem of course being that attr1 is and attr2 are strings.. So I can't do something like thing."attr1"

I've tried doing: thing.send(k,v) but that doesn't work

Was it helpful?

Solution

Use thing.send("#{k}=", v) instead.

OTHER TIPS

You need to call the setter method, which for an attribute called name would be name=. Following from your example:

attr_hash.each do |k,v|
  thing.send("#{k}=", v)
end

Also, if this hash is coming from the user somehow, it might be a good idea to test if the setter exists before calling it, using respond_to?:

attr_hash.each do |k,v|
  setter = "#{k}="
  thing.send(setter, v) if thing.respond_to?(setter)
end

OpenStruct does it for you.

require 'ostruct'
attr_hash = {"attr1"=>"val1", "attr2"=>"val2"}
d = OpenStruct.new(attr_hash)
p d.attr1 #=> "val1"
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top