Question

Je veux juste connaître le meilleur moyen d'émuler une énumération de style C # en Ruby.

Était-ce utile?

La solution

  

Plus précisément, j'aimerais pouvoir effectuer des tests logiques par rapport à l'ensemble de valeurs donné à une variable. Exemple: l’état d’une fenêtre: "minimisé, maximisé, fermé, ouvert"

Si vous avez besoin que les énumérations correspondent aux valeurs (par exemple, vous devez minimisé pour égaler 0, maximisé pour être égal à 100, etc.) J'utiliserais un hachage de symboles en valeurs, comme ceci:

WINDOW_STATES = { :minimized => 0, :maximized => 100 }.freeze

Le gel (comme le dit nate) vous empêche de tout casser à l'avenir par accident. Vous pouvez vérifier si quelque chose est valide en faisant ceci

WINDOW_STATES.keys.include?(window_state)

Sinon, si vous n'avez besoin d'aucune valeur et que vous devez simplement cocher 'appartenance', alors un tableau est bien

WINDOW_STATES = [:minimized, :maximized].freeze

Utilisez-le comme ceci

WINDOW_STATES.include?(window_state)

Si vos clés doivent être des chaînes (comme par exemple un champ "Etat" dans une application RoR), vous pouvez utiliser un tableau de chaînes. Je le fais TOUT LE TEMPS dans beaucoup de nos applications de rails.

WINDOW_STATES = %w(minimized maximized open closed).freeze

C’est à peu près ce pour quoi le validateur rails validates_inclusion_of est conçu à cet effet: -)

Note personnelle:

Je n'aime pas taper include? tout le temps, donc j'ai ce (c'est compliqué seulement à cause du cas .in? (1, 2, 3):

class Object

    # Lets us write array.include?(x) the other way round
    # Also accepts multiple args, so we can do 2.in?( 1,2,3 ) without bothering with arrays
    def in?( *args )
        # if we have 1 arg, and it is a collection, act as if it were passed as a single value, UNLESS we are an array ourselves.
        # The mismatch between checking for respond_to on the args vs checking for self.kind_of?Array is deliberate, otherwise
        # arrays of strings break and ranges don't work right
        args.length == 1 && args.first.respond_to?(:include?) && !self.kind_of?(Array) ?
            args.first.include?( self ) :
            args.include?( self )
        end
    end
end

Ceci vous permet de taper

window_state.in? WINDOW_STATES

Autres conseils

Ce n'est pas tout à fait pareil, mais je construis souvent un hash pour ce genre de chose:

STATES = {:open => 1, :closed => 2, :max => 3, :min => 4}.freeze()

Le fait de geler le hachage m'empêche d'en modifier accidentellement le contenu.

De plus, si vous souhaitez générer une erreur lorsque vous accédez à quelque chose qui n'existe pas, vous pouvez utiliser un Proc par défaut pour le faire:

STATES = Hash.new { |hash, key| raise NameError, "#{key} is not allowed" }
STATES.merge!({:open => 1, :closed => 2, :max => 3, :min => 4}).freeze()

STATES[:other] # raises NameError

Je ne pense pas que Ruby supporte les vrais enums - bien qu'il existe encore des solutions.

Enumérations et Ruby

La méthode la plus simple pour définir un Enum dans ruby ??consiste à utiliser une classe avec des variables constantes.

class WindowState
  Open = 1
  Closed = 2
  Max = 3
  Min = 4
end

Faire un cours ou un hachage, comme d’autres l’ont dit, fonctionnera. Cependant, Ruby doit utiliser symboles . Les symboles en Ruby commencent par deux points et ressemblent à ceci:

greetingtype = :hello

Ils sont un peu comme des objets qui consistent uniquement en un nom.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top