Как программно добавить атрибуты к объектам?

У меня есть массив хэшей, который я бы предпочел превратить в массив объектов с атрибутами, программно добавленными к этим объектам.

Я сейчас попробую

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)
Другие вопросы по тегам