Literal enums
Literal enums are a way to define a set of named values. Each member of the enum is an instance of the enum class, which also acts as a namespace for the members.
class Color < Literal::Enum(Integer)
Red = new(1)
Green = new(2)
Blue = new(3)
end
Here, we defined an enum Color
with three members: Red
, Green
, and Blue
. Each member is an instance of the Color
class, and has an associated value. The value must match the type specified — in this case Integer
.
You must specify each value by hand because Enums are usually serialized and stored in a database by their value. If we were to automatically assign values, the order of the members would be significant, and simply changing the order would break things.
TIP
If you’re using TruffleRuby, you will need to call __after_defined__
at the end of your enum class, since TruffleRuby doesn’t support end
TracePoints.
Enumeration methods
Enums have a few class methods to help you work with them.
members
Returns a Set of all members of the enum.
Color.members # => [Color::Red, Color::Green, Color::Blue]
values
Returns an Array of all values of the enum.
Color.values # => [1, 2, 3]
[]
or cast
Takes a value and return the corresponding member of the enum.
Color[1] # => Color::Red
Color.cast(2) # => Color::Green
Enumerable
Enums are Enumerable, so you can use all the methods that come with it.
Color.each do |color|
puts color.name
end
Instance methods
Enums have a few instance methods to help you work with them.
value
Returns the value of the member.
Color::Red.value # => 1
name
Returns the name of the member.
Color::Red.name # => "Color::Red"
Automatic identity predicates
Enums have automatic identity predicate based on each member’s name.
color = Color::Red
color.red? # => true
color.green? # => false
Properties
You can define properties on Enums just like other structured Literal objects.
class Color < Literal::Enum(Integer)
prop :hex, String
Red = new(1, hex: "FF0000")
Green = new(2, hex: "00FF00")
Blue = new(3, hex: "0000FF")
end
Methods
Because each member is an instance of its class, you can define instance methods on the class for each member.
class Color < Literal::Enum(Integer)
prop :hex, String
Red = new(1, hex: "FF0000")
Green = new(2, hex: "00FF00")
Blue = new(3, hex: "0000FF")
def rgb
hex.scan(/.{2}/).map { |it| it.to_i(16) }
end
end
Indexing
You can index enums by their value or name.
class Color < Literal::Enum(Integer)
prop :hex, String
# Index by value
index :hex, String, unique: true
# Index with a block
index :lower_hex, String, unique: true do |color|
color.hex.downcase
end
Red = new(1, hex: "FF0000")
Green = new(2, hex: "00FF00")
Blue = new(3, hex: "0000FF")
def rgb
hex.scan(/.{2}/).map { |it| it.to_i(16) }
end
end
The index allows you to use where
for exact-match values.
Color.where(lower_hex: "0000ff") # => [Color::Blue]
If the index is unique, you can use find_by
for exact-match values.
Color.find_by(lower_hex: "0000ff") # => Color::Blue