Domanda

Voglio solo sapere il modo migliore per emulare un'enumerazione in stile C # in Ruby.

È stato utile?

Soluzione

  

In particolare, vorrei essere in grado di eseguire test logici rispetto all'insieme di valori dati alcune variabili. Esempio potrebbe essere lo stato di una finestra: " minimized, maximized, closed, open "

Se hai bisogno delle enumerazioni per mappare i valori (ad esempio, devi minimizzarli su 0, massimizzare su 100, ecc.) Userei un hash di simboli sui valori, come questo:

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

Il congelamento (come dice Nate) ti impedisce di rompere le cose in futuro per caso. Puoi verificare se qualcosa è valido facendo questo

WINDOW_STATES.keys.include?(window_state)

In alternativa, se non hai bisogno di alcun valore e devi solo controllare 'appartenenza', allora un array va bene

WINDOW_STATES = [:minimized, :maximized].freeze

Usalo in questo modo

WINDOW_STATES.include?(window_state)

Se le tue chiavi diventeranno stringhe (come ad esempio un campo 'state' in un'app RoR), puoi usare un array di stringhe. Lo faccio TUTTO IL TEMPO in molte delle nostre app Rails.

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

Questo è praticamente ciò che rails validates_inclusion_of validator è appositamente progettato per :-)

Nota personale:

Non mi piace digitare include? tutto il tempo, quindi ho questo (è complicato solo per il caso .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

Questo ti permette di digitare

window_state.in? WINDOW_STATES

Altri suggerimenti

Non è esattamente lo stesso, ma spesso costruirò un hash per questo tipo di cose:

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

Il congelamento dell'hash mi impedisce di modificare accidentalmente il suo contenuto.

Inoltre, se si desidera generare un errore quando si accede a qualcosa che non esiste, è possibile utilizzare un Proc predefinito per farlo:

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

Non credo che Ruby supporti i veri enum - tuttavia, ci sono ancora soluzioni disponibili.

Enumerations and Ruby

Il modo più semplice per definire un Enum in ruby ??per usare una classe con variabili costanti.

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

Fare una lezione o un hash come altri hanno detto funzionerà. Tuttavia, la cosa di Ruby da fare è usare simboli . I simboli in Ruby iniziano con i due punti e assomigliano a questo:

greetingtype = :hello

Sono oggetti simili che consistono solo in un nome.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top