Как программно добавить атрибуты к объектам? - PullRequest
0 голосов
/ 03 марта 2012

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

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

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 Ответ

5 голосов
/ 03 марта 2012

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...