Ruby: Метапрограммирование методов из хэша - PullRequest
3 голосов
/ 19 июля 2011

Меня интересует создание объекта из хэша, сгенерированного файлом Yaml.

Файл Yaml может выглядеть примерно так:

foos:
  first:
    code: f
    name: The First Foo
    icon: path/to/file.png
  second:
    code: s
    name: The Second Foo
    icon: path/to/file.png
bars:
  dive:
    code: d
    name: Dive Bar
    location: 100 Main St.
  college:
    code: c
    name: College Bar
    location: 100 University Ave.

Итак, файл yamlв основном определяет набор атрибутов, которые принадлежат категориям.У категорий есть имя (foos, bars), и у каждого атрибута есть как минимум код и имя.

Итак, я хотел бы иметь возможность создать модель «Атрибуты», которая поворачиваетимена категорий в методы, которые могут вызывать элементы в этой категории как простые объекты.

Я хотел бы иметь возможность сделать что-то вроде:

Attributes = Attributes.new(...yaml_file...)
Attributes.foos #returns an array of foos
Attributes.foo(:f) #returns the foo with a code (f)
Attributes.foo(:s).name #returns "The Second Foo"

Я немного потерянкак к этому подойти.

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

Я знаю, что с хэшем я уже мог сделать

attributes[:foos][:first][:icon] 

Но я бы хотел использовать эту модель из хэша в качестве отправной точки, где я смогу позже добавить другие полезные методы в модель атрибутов.Кроме того, я довольно новичок в ruby, и мне бы очень хотелось научиться делать что-то подобное только ради этого.

Спасибо за любую помощь!

1 Ответ

1 голос
/ 19 июля 2011

Предполагая, что ваша модель обрабатывается и хранится в хеш-хеше, вы можете использовать method_missing для реализации вашей схемы. Очень грубый набросок этого:

class Attributes {
  def init(*args) {
    @hash = # ....
  }
  def method_missing(symbol, *args)
    result = @hash[symbol]
    if (result && args.length) {
      return result[args[0]]
    }
    return result
  }
}
...