Как программно добавить атрибуты к объектам?
У меня есть массив хэшей, который я бы предпочел превратить в массив объектов с атрибутами, программно добавленными к этим объектам.
Я сейчас попробую
obj = OpenStruct.new
resulthash["users"].collect { |u|
u.each do |k,v|
obj.send("#{k}=#{v}");
end
}
Напомним, я пытаюсь сделать
obj.foo = "bar"
obj.hello = "world"
Но программно если например к массиву / хешу выглядело вот так
{"users"=>[{"foo"=>"bar","hello"=>"world"}]}
1 ответ
Object#send
принимает имя метода в качестве первого аргумента и, необязательно, аргументы для передачи методу в качестве оставшихся аргументов.
Таким образом, obj.send("#{k}=#{v}")
на самом деле пытается вызвать методы с именем что-то вроде "foo=bar"
, что не то же самое, что звонить foo=
с аргументом "bar"
,
Таким образом, правильный путь будет
resulthash["users"].each { |u|
u.each do |k,v|
obj.send("#{k}=", v)
end
}
Обратите внимание, что я использую #each
и не #collect
потому что мы не хотим преобразовывать хэш.
Кроме того, если ваш пример отражает вашу конечную цель - просто преобразовать массив хэшей в один OpenStruct, вы можете просто объединить все хэши в один и передать их OpenStruct.new
:
h = resulthash["users"].inject({}) { |acc, v| acc.merge(v) }
obj = OpenStruct.new(h)