Как переместить это в базовый класс, это перечисление Ruby - PullRequest
1 голос
/ 02 ноября 2010

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

class Blah

 def Blah.add_item(key, value)
   @hash ||= {}
   @hash[key] = value
 end

 def Blah.const_missing(key)
   @hash[key]
 end

 def Blah.each
   @hash.each {|key, value| yield(key, value)}
 end

end
  1. У меня есть другие перечисления, которые мне нужны, могу ли яКак-то из этого создать базовый класс, чтобы мне не приходилось повторять методы add_item, const_missng и .each для каждого?

  2. При создании файла для всех моих перечислений я ставлюэто в /lib/enums.rb, это хорошая практика?

  3. Должен ли я поместить этот класс в модуль, т.е. я полагаю, вы делаете это для пространства имен, верно?

Ответы [ 2 ]

2 голосов
/ 02 ноября 2010

Ответ DigitalRoss хороший.Я представлю альтернативу.Предположим, вы хотите, чтобы все ваши перечисления жили в модуле.Все, что вам нужно, это маленький модуль перечисления, например:

module Enumeration

  include Enumerable

  def self.included(m)
    m.extend self
  end

  def each(&block)
    constants.find_all do |name|
      name =~ /^[A-Z_\d]+$/
    end.map do |name|
      [name, const_get(name)]
    end.sort_by(&:last).each(&block)
  end

end

Когда вам нужно перечисление, создайте для него модуль, включите Enumeration и определите ваши ключи и значения как константы со всеми заглавными буквамиnames.

module States
  include Enumeration
  INIT = 1
  RUN = 2
  DONE = 3
end

Модуль ответит на любой из методов, предоставленных Enumerable:

p States.to_a
# => [["INIT", 1], ["RUN", 2], ["DONE", 3]]

Вы можете обнаружить, что иногда вам все равно, какие значения есть,просто они разные.Давайте добавим в Enumeration метод value, который упрощает создание констант с автоматически увеличивающимися ключами:

module Enumeration

  def value(name, value = next_value)
    const_set(name, value)
  end

  def next_value
    (map(&:last).max || 0) + 1
  end

end

Теперь давайте рассмотрим несколько планет:

module Planets
  include Enumeration
  value :MERCURY
  value :VENUS
  value :EARTH
end

p Planets.to_a
# => [["MERCURY", 1], ["VENUS", 2], ["EARTH", 3]]

Конечно, этиперечисления - это просто коллекции нормальных констант, поэтому вы можете использовать их напрямую:

p Planets::MERCURY    # => 1
2 голосов
/ 02 ноября 2010
  1. Вы можете просто использовать Blah в качестве базового класса.

    class C

    класс D <бла;end </p>

  2. Я думаю, я мог бы просто добавить его с исходным кодом каждого проекта, с которым он используется.Да, DIE, DRY и все такое, но это особенно важно в построчном коде.Это довольно распространенная практика объединения внешнего программного обеспечения с каждым проектом.

  3. Нет.Это уже класс, поэтому он использует только одно имя.Поместите модуль вокруг кода, который использует Blah, проект или раздел проекта.Это будет большим и более нуждающимся в пространстве имен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...