Как реализовать Enums в Ruby? - PullRequest
       92

Как реализовать Enums в Ruby?

301 голосов
/ 16 сентября 2008

Какой лучший способ реализовать идиому enum в Ruby? Я ищу что-то, что я могу использовать (почти), например перечисления Java / C #.

Ответы [ 26 ]

1 голос
/ 22 августа 2015

Иногда все, что мне нужно, - это получить значение enum и идентифицировать его имя, подобное миру java.

module Enum
     def get_value(str)
       const_get(str)
     end
     def get_name(sym)
       sym.to_s.upcase
     end
 end

 class Fruits
   include Enum
   APPLE = "Delicious"
   MANGO = "Sweet"
 end

 Fruits.get_value('APPLE') #'Delicious'
 Fruits.get_value('MANGO') # 'Sweet'

 Fruits.get_name(:apple) # 'APPLE'
 Fruits.get_name(:mango) # 'MANGO'

Это для меня служит цели enum и делает ее очень расширяемой. Вы можете добавить больше методов в класс Enum, и альты получат их бесплатно во всех определенных перечислениях. например. get_all_names и тому подобное.

0 голосов
/ 31 мая 2019

Быстро и грязно, похоже на C #:

class FeelsLikeAnEnum
  def self.Option_1() :option_1 end
  def self.Option_2() :option_2 end
  def self.Option_3() :option_3 end
end

Используйте его так же, как если бы вы использовали Enum:

method_that_needs_options(FeelsLikeAnEnum.Option_1)
0 голосов
/ 11 января 2018

Попробуйте инум. https://github.com/alfa-jpn/inum

class Color < Inum::Base
  define :RED
  define :GREEN
  define :BLUE
end
Color::RED 
Color.parse('blue') # => Color::BLUE
Color.parse(2)      # => Color::GREEN

подробнее https://github.com/alfa-jpn/inum#usage

0 голосов
/ 29 сентября 2009

Другой подход заключается в использовании класса Ruby с хешем, содержащим имена и значения, как описано в следующем сообщении в блоге RubyFleebie . Это позволяет легко преобразовывать значения и константы (особенно если вы добавляете метод класса для поиска имени для данного значения).

0 голосов
/ 04 апреля 2010

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

0 голосов
/ 30 декабря 2012

Еще один способ имитировать перечисление с последовательной обработкой равенства (бессовестно принятый от Дейва Томаса). Позволяет открывать перечисления (как символы) и закрытые (предопределенные) перечисления.

class Enum
  def self.new(values = nil)
    enum = Class.new do
      unless values
        def self.const_missing(name)
          const_set(name, new(name))
        end
      end

      def initialize(name)
        @enum_name = name
      end

      def to_s
        "#{self.class}::#@enum_name"
      end
    end

    if values
      enum.instance_eval do
        values.each { |e| const_set(e, enum.new(e)) }
      end
    end

    enum
  end
end

Genre = Enum.new %w(Gothic Metal) # creates closed enum
Architecture = Enum.new           # creates open enum

Genre::Gothic == Genre::Gothic        # => true
Genre::Gothic != Architecture::Gothic # => true
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...