How can I use C # style enumerations in Ruby?

I just want to know how best to emulate a C # style enumeration in Ruby.

+8
ruby enumeration
Oct 02 '08 at 21:36
source share
5 answers

In particular, I would like to be able to perform logical tests against the set of values โ€‹โ€‹given by a variable. An example would be the state of a window: "minimized, maximized, closed, open"

If you need enumerations to map to values โ€‹โ€‹(for example, you need to minimize equal to 0, maximum equal to 100, etc.), I would use a hash of characters for the values, for example:

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

Freezing (for example, says Nate) will prevent you from accidentally hacking things in the future. You can check if this is really done by doing this.

 WINDOW_STATES.keys.include?(window_state) 

Alternatively, if you don't need any values, and you just need to check the โ€œmembershipโ€ then the array will be good

 WINDOW_STATES = [:minimized, :maximized].freeze 

Use it like this:

 WINDOW_STATES.include?(window_state) 

If your keys are strings (for example, the status field in a RoR application), you can use an array of strings. I do this ALL TIME in many of our rail applications.

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

This is pretty much what validates_inclusion_of validator rails is for :-)

Personal note:

I don't like typing? all the time, so I have this (this only gets complicated due to the .in? case (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 

This allows you to enter

 window_state.in? WINDOW_STATES 
+5
Oct 02 '08 at 22:24
source share

This is not exactly the same, but I often create a hash for this kind of thing:

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

Freezing a hash prevents its contents from being accidentally modified.

Also, if you want to raise an error when accessing something that does not exist, you can use defualt Proc for this:

 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 
+5
Oct 02 '08 at 22:09
source share

I don't think Ruby supports true enumerations - although there are solutions available.

Enums and Ruby

+3
Oct 02 '08 at 21:43
source share

The easiest way to define Enum in ruby โ€‹โ€‹to use a class with constant variables.

 class WindowState Open = 1 Closed = 2 Max = 3 Min = 4 end 
+3
Oct 02 '08 at 22:02
source share

Creating a class or hash, as others have said, will work. However, for Ruby, you need to use symbols . Characters in Ruby begin with a colon and look like this:

 greetingtype = :hello 

They are similar to objects consisting only of a name.

+1
Oct 02 '08 at 22:15
source share



All Articles