Ruby::Enum
Enum-like behavior for Ruby, heavily inspired by this, and improved upon another blog post.
Table of Contents
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 OrderState
include Ruby::Enum
define :CREATED, 'created'
define :PAID, 'paid'
end
OrderState::CREATED # 'created'
OrderState::PAID # 'paid'
OrderState::UNKNOWN # raises Ruby::Enum::Errors::UninitializedConstantError
OrderState.keys # [ :CREATED, :PAID ]
OrderState.values # [ 'created', 'paid' ]
OrderState.to_h # { :CREATED => 'created', :PAID => 'paid' }
Class Methods
Define enums, and 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' }
Default Value
The value is optional. If unspecified, the value will default to the key.
class OrderState
include Ruby::Enum
define :UNSPECIFIED
define :unspecified
end
OrderState::UNSPECIFIED # :UNSPECIFIED
OrderState.unspecified # :unspecified
Enumerating
Enums support all Enumerable
methods.
Iterating
OrderState.each do |key, enum|
# key and enum.key are :CREATED, :PAID
# enum.value is 'created', 'paid'
end
OrderState.each_key do |key|
# :CREATED, :PAID
end
OrderState.each_value do |value|
# 'created', 'paid'
end
Mapping
OrderState.map do |key, enum|
# key and enum.key are :CREATED, :PAID
# enum.value is 'created', 'paid'
[enum.value, key]
end
# => [ ['created', :CREATED], ['paid', :PAID] ]
Reducing
OrderState.reduce([]) do |arr, (key, enum)|
# key and enum.key are :CREATED, :PAID
# enum.value is 'created', 'paid'
arr << [enum.value, key]
end
# => [ ['created', :CREATED], ['paid', :PAID] ]
Sorting
OrderState.sort_by do |key, enum|
# key and enum.key are :CREATED, :PAID
# enum.value is 'created', 'paid'
enum.value.length
end
# => [[:PAID, #<OrderState:0x0 @key=:PAID, @value="paid">], [:CREATED, #<OrderState:0x1 @key=:CREATED, @value="created">]]
Hashing
Several hash-like methods are supported.
Retrieving keys and values
OrderState.keys
# => [:CREATED, :PAID]
OrderState.values
# => ['created', 'paid']
Mapping keys to values
OrderState.key?(:CREATED)
# => true
OrderState.value(:CREATED)
# => 'created'
OrderState.key?(:FAILED)
# => false
OrderState.value(:FAILED)
# => nil
Mapping values to keys
OrderState.value?('paid')
# => true
OrderState.key('paid')
# => :PAID
OrderState.value?('failed')
# => false
OrderState.key('failed')
# => nil
Duplicate enumerator keys or duplicate values
Defining duplicate enums raises Ruby::Enum::Errors::DuplicateKeyError
.
class OrderState
include Ruby::Enum
define :CREATED, 'created'
define :CREATED, 'recreated' # raises DuplicateKeyError
end
Defining a duplicate value raises Ruby::Enum::Errors::DuplicateValueError
.
class OrderState
include Ruby::Enum
define :CREATED, 'created'
define :RECREATED, 'created' # raises DuplicateValueError
end
The DuplicateValueError
exception is raised to be consistent with the unique key constraint. Since keys are unique, there needs to be a way to map values to keys using OrderState.value('created')
.
Inheritance
When 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.
class OrderState
include Ruby::Enum
define :CREATED, 'CREATED'
define :PAID, 'PAID'
end
class ShippedOrderState < OrderState
define :PREPARED, 'PREPARED'
define :SHIPPED, 'SHIPPED'
end
ShippedOrderState::CREATED # 'CREATED'
ShippedOrderState::PAID # 'PAID'
ShippedOrderState::PREPARED # 'PREPARED'
ShippedOrderState::SHIPPED # 'SHIPPED'
The values
class method will enumerate the values from all base classes.
OrderState.values # ['CREATED', 'PAID']
ShippedOrderState.values # ['CREATED', 'PAID', 'PREPARED', SHIPPED']
Contributing
You're encouraged to contribute to ruby-enum. See CONTRIBUTING for details.
Copyright and License
Copyright (c) 2013-2021, Daniel Doubrovkine and Contributors.
This project is licensed under the MIT License.
Related Projects
- typesafe_enum: Typesafe enums, inspired by Java.
- renum: A readable, but terse enum.