Ruby::Enum

Gem Version Build Status Code Climate

Enum-like behavior for Ruby, heavily inspired by this and improved upon another blog post.

Usage

Enums can be defined and accessed either as constants or class methods, which is a matter of preference.

Constants

Define enums and reference them as constants.

class Colors
  include Ruby::Enum

  define :RED, "red"
  define :GREEN, "green"
end
Colors::RED # "red"
Colors::GREEN # "green"
Colors::UNDEFINED # raises Ruby::Enum::Errors::UninitializedConstantError
Colors.keys # [ :RED, :GREEN ]
Colors.values # [ "red", "green" ]
Colors.to_h # { :RED => "red", :GREEN => "green" }

Class Methods

Define enums reference them as class methods.

class OrderState
  include Ruby::Enum

  define :created, 'Created'
  define :paid, 'Paid'
end
OrderState.created # "Created"
OrderState.paid # "Paid"
OrderState.undefined # NoMethodError is raised
OrderState.keys # [ :created, :paid ]
OrderState.values # ["Created", "Paid"]
OrderState.to_h # { :created => 'Created', :paid => 'Paid' }

Enumerating

All Enumerable methods are supported.

Iterating

Colors.each do |key, enum|
  # key and enum.key is :RED, :GREEN
  # enum.value is "red", "green"
end
Colors.each_key do |key|
  # :RED, :GREEN
end
Colors.each_value do |value|
  # "red", "green"
end

Mapping

Colors.map do |key, enum|
  # key and enum.key is :RED, :GREEN
  # enum.value is "red", "green"
  [enum.value, key]
end

# => [ ['red', :RED], ['green', :GREEN] ]

Reducing

Colors.reduce([]) do |arr, (key, enum)|
  # key and enum.key is :RED, :GREEN
  # enum.value is "red", "green"
  arr << [enum.value, key]
end

# => [ ['red', :RED], ['green', :GREEN] ]

Sorting

Colors.sort_by do |key, enum|
  # key and enum.key is :RED, :GREEN
  # enum.value is "red", "green"
  enum.value
end

# => [ [:GREEN, #<Colors:...>], [:RED, #<Colors:...>] ]

Hashing

Several hash-like methods are supported.

Retrieving keys and values

Colors.keys
# => [:RED, :GREEN]

Colors.values
# => ["red", "green"]

Mapping keys to values

Colors.key?(:RED)
# => true

Colors.value(:RED)
# => "red"

Colors.key?(:BLUE)
# => false

Colors.value(:BLUE)
# => nil

Mapping values to keys

Colors.value?('green')
# => true

Colors.key('green')
# => :GREEN

Colors.value?('yellow')
# => false

Colors.key('yellow')
# => nil

Duplicate enumerator keys or duplicate values

Defining duplicate enums will raise a Ruby::Enum::Errors::DuplicateKeyError. Moreover a duplicate value is not allowed. Defining a duplicate value will raise a Ruby::Enum::Errors::DuplicateValueError. The following declarations will both raise an exception:

  class Colors
    include Ruby::Enum

    define :RED, "red"
    define :RED, "my red" # will raise a DuplicateKeyError exception
  end

  # The following will raise a DuplicateValueError
  class Colors
    include Ruby::Enum

    define :RED, 'red'
    define :SOME, 'red' # Boom
  end

The DuplicateValueError exception is thrown to be consistent with the unique key constraint. Since keys are unique there is no way to map values to keys using Colors.value('red')

Inheritance behavior

Inheriting from a Ruby::Enum class, all defined enums in the parent class will be accessible in sub classes as well. Sub classes can also provide extra enums as usual.

Contributing

You're encouraged to contribute to this gem. See CONTRIBUTING for details.

Copyright (c) 2013-2020, Daniel Doubrovkine and Contributors.

This project is licensed under the MIT License.