371 votes

Enums en Ruby

Quelle est la meilleure façon de mettre en œuvre l’idiome enum en Ruby ? Je suis à la recherche de quelque chose que je peux utiliser (presque) comme le Java / C# enums.

371voto

mlibby Points 2805

Deux façons. Symboles ( notation) ou constantes ( notation).

Les symboles sont appropriés lorsque vous voulez améliorer la lisibilité sans code d’ordures avec les chaînes littérales.

Les constantes sont appropriés lorsque vous avez une valeur sous-jacente qui est importante. Simplement déclarer un module pour contenir vos constantes et ensuite déclarer les constantes au sein de qui.

63voto

Charles Points 2878

Je suis surpris que personne n'a offert quelque chose comme ce qui suit (récoltées à partir de la RAPI gem):

class Enum

  private

  def self.enum_attr(name, num)
    name = name.to_s

    define_method(name + '?') do
      @attrs & num != 0
    end

    define_method(name + '=') do |set|
      if set
        @attrs |= num
      else
        @attrs &= ~num
      end
    end
  end

  public

  def initialize(attrs = 0)
    @attrs = attrs
  end

  def to_i
    @attrs
  end
end

Qui peut être utilisé comme:

class FileAttributes < Enum
  enum_attr :readonly,       0x0001
  enum_attr :hidden,         0x0002
  enum_attr :system,         0x0004
  enum_attr :directory,      0x0010
  enum_attr :archive,        0x0020
  enum_attr :in_rom,         0x0040
  enum_attr :normal,         0x0080
  enum_attr :temporary,      0x0100
  enum_attr :sparse,         0x0200
  enum_attr :reparse_point,  0x0400
  enum_attr :compressed,     0x0800
  enum_attr :rom_module,     0x2000
end

Exemple:

>> example = FileAttributes.new(3)
=> #<FileAttributes:0x629d90 @attrs=3>
>> example.readonly?
=> true
>> example.hidden?
=> true
>> example.system?
=> false
>> example.system = true
=> true
>> example.system?
=> true
>> example.to_i
=> 7

Ce qui est bien dans la base de données de scénarios, ou lorsque vous traitez avec style C des constantes/énumérations (comme c'est le cas lors de l'utilisation de FFI, qui RAPI fait un usage intensif de).

Aussi, vous n'avez pas à vous soucier des fautes de frappe provoquant le silence des échecs, comme vous le feriez avec l'aide d'un hachage de type de solution.

57voto

Alexey Points 2956

I l'utilisation de cette approche:

MyEnum = [MyValue1 = 'value1', MyValue2 = 'value2']

Je l'aime pour les avantages suivants:

  1. Il regroupe des valeurs visuellement comme un ensemble de
  2. Il fait un peu de compilation-le temps de vérifier (en contraste avec juste l'aide de symboles)
  3. Je peux facilement accéder à la liste de toutes les valeurs possibles: juste MyEnum
  4. Je peux facilement accéder à des valeurs distinctes: MyValue1
  5. Il peut être la valeur de tout temps, pas seulement Symbole

Les symboles peuvent me cause plus vous n'avez pas à écrire le nom de l'extérieur de la classe, si vous l'utilisez dans une autre classe (MyClass::MyValue1)

52voto

emk Points 27772

Pour ce faire, la plus idiomatique consiste à utiliser des symboles. Par exemple, au lieu de :

.. .vous pouvez simplement utiliser des symboles :

C’est un peu plus ouverte que les enums, mais il correspond bien à l’esprit de Ruby.

Symboles effectuent aussi très bien. En comparant les deux symboles pour l’égalité, par exemple, est beaucoup plus rapide que la comparaison de deux chaînes.

12voto

toplex Points 86

Je sais que ça a été un long temps depuis que le gars a posté cette question, mais j'ai eu la même question, et ce post ne m'a pas donné la réponse. Je voulais un moyen facile de voir ce que ce nombre représente, en faciliter la comparaison, et la plupart de tous les ActiveRecord de soutien pour la recherche de l'aide de la colonne représentant la enum.

Je n'ai rien trouvé, j'ai donc fait une impressionnante mise en œuvre appelée yinum qui a permis tout ce que je cherchais. Faites tonne de specs, donc je suis assez sûr qu'il est sécuritaire. Profitez-en!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X