Class: Philiprehberger::Enum
- Inherits:
-
Object
- Object
- Philiprehberger::Enum
- Extended by:
- Enumerable
- Includes:
- Comparable
- Defined in:
- lib/philiprehberger/enum.rb,
lib/philiprehberger/enum/version.rb
Overview
Type-safe enumerations with ordinals, custom values, and pattern matching.
Subclass Enum and use the ‘member` class method to define members:
class Status < Philiprehberger::Enum
member :draft
member :published
member :archived
end
Defined Under Namespace
Classes: Error
Constant Summary collapse
- VERSION =
'0.4.0'
Instance Attribute Summary collapse
-
#name ⇒ Symbol
readonly
The member name.
-
#ordinal ⇒ Integer
readonly
The ordinal position (declaration order).
-
#value ⇒ Object?
readonly
The custom value, or nil if not set.
Class Method Summary collapse
-
.each {|Enum| ... } ⇒ Enumerator
Yield each member in declaration order.
-
.fetch(name) ⇒ Enum
Look up a member by name, raising if not found.
-
.fetch_by_value(val) ⇒ Enum
Look up a member by value, raising if not found.
-
.first ⇒ Enum?
Return the first declared member.
-
.from_name(name) ⇒ Enum?
Look up a member by its name, with case-insensitive fallback.
-
.from_string(string) ⇒ Enum?
Look up a member by its string representation.
-
.from_value(val) ⇒ Enum?
Look up a member by its custom value.
-
.last ⇒ Enum?
Return the last declared member.
-
.member(name, value: nil) ⇒ Enum
Define a new member on this enum class.
-
.members ⇒ Array<Enum>
Return all members in declaration order.
-
.members_by_value ⇒ Hash{Object => Enum}
Return a reverse lookup hash of values to members.
-
.names ⇒ Array<Symbol>
Return all member names in declaration order.
-
.sample(n = nil) ⇒ Enum+
Return a random member or array of random members.
-
.size ⇒ Integer
(also: count)
Return the number of defined members.
-
.slice(*names) ⇒ Array<Enum>
Return members matching the given symbol names, silently skipping unknown names.
-
.to_h ⇒ Hash{Symbol => Object}
Return a hash of name symbols to values.
-
.valid?(name) ⇒ Boolean
Check if a name is a valid member.
-
.values ⇒ Array<Object>
Return all member values in declaration order.
Instance Method Summary collapse
-
#<=>(other) ⇒ Integer?
Compare members by ordinal.
-
#deconstruct_keys(keys) ⇒ Hash
Support Ruby 3.x pattern matching with ‘in` expressions.
-
#initialize(name, ordinal, value) ⇒ Enum
constructor
A new instance of Enum.
-
#inspect ⇒ String
A human-readable representation.
-
#to_json(*args) ⇒ String
Serialize to a JSON-compatible hash.
-
#to_s ⇒ String
The member name as a string.
Constructor Details
#initialize(name, ordinal, value) ⇒ Enum
Returns a new instance of Enum.
34 35 36 37 38 39 |
# File 'lib/philiprehberger/enum.rb', line 34 def initialize(name, ordinal, value) @name = name @ordinal = ordinal @value = value freeze end |
Instance Attribute Details
#name ⇒ Symbol (readonly)
Returns the member name.
23 24 25 |
# File 'lib/philiprehberger/enum.rb', line 23 def name @name end |
#ordinal ⇒ Integer (readonly)
Returns the ordinal position (declaration order).
26 27 28 |
# File 'lib/philiprehberger/enum.rb', line 26 def ordinal @ordinal end |
#value ⇒ Object? (readonly)
Returns the custom value, or nil if not set.
29 30 31 |
# File 'lib/philiprehberger/enum.rb', line 29 def value @value end |
Class Method Details
.each {|Enum| ... } ⇒ Enumerator
Yield each member in declaration order
84 85 86 87 |
# File 'lib/philiprehberger/enum.rb', line 84 def each(&) freeze_members! member_registry.values.each(&) end |
.fetch(name) ⇒ Enum
Look up a member by name, raising if not found
176 177 178 |
# File 'lib/philiprehberger/enum.rb', line 176 def fetch(name) from_name(name) || raise(Error, "no member #{name.inspect} on #{self}") end |
.fetch_by_value(val) ⇒ Enum
Look up a member by value, raising if not found
185 186 187 |
# File 'lib/philiprehberger/enum.rb', line 185 def fetch_by_value(val) from_value(val) || raise(Error, "no member with value #{val.inspect} on #{self}") end |
.first ⇒ Enum?
Return the first declared member
208 209 210 211 |
# File 'lib/philiprehberger/enum.rb', line 208 def first freeze_members! member_registry.values.first end |
.from_name(name) ⇒ Enum?
Look up a member by its name, with case-insensitive fallback
148 149 150 151 152 |
# File 'lib/philiprehberger/enum.rb', line 148 def from_name(name) freeze_members! key = name.to_sym member_registry[key] || member_registry.values.find { |m| m.name.to_s.downcase == key.to_s.downcase } end |
.from_string(string) ⇒ Enum?
Look up a member by its string representation
158 159 160 |
# File 'lib/philiprehberger/enum.rb', line 158 def from_string(string) from_name(string) end |
.from_value(val) ⇒ Enum?
Look up a member by its custom value
166 167 168 169 |
# File 'lib/philiprehberger/enum.rb', line 166 def from_value(val) freeze_members! member_registry.values.find { |m| m.value == val } end |
.last ⇒ Enum?
Return the last declared member
216 217 218 219 |
# File 'lib/philiprehberger/enum.rb', line 216 def last freeze_members! member_registry.values.last end |
.member(name, value: nil) ⇒ Enum
Define a new member on this enum class
95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/philiprehberger/enum.rb', line 95 def member(name, value: nil) raise Error, "cannot add members to #{self} after freeze" if @frozen name = name.to_sym raise Error, "member #{name} is already defined on #{self}" if member_registry.key?(name) ord = member_registry.size instance = new(name, ord, value) member_registry[name] = instance const_set(name.upcase, instance) instance end |
.members ⇒ Array<Enum>
Return all members in declaration order
113 114 115 116 |
# File 'lib/philiprehberger/enum.rb', line 113 def members freeze_members! member_registry.values.freeze end |
.members_by_value ⇒ Hash{Object => Enum}
Return a reverse lookup hash of values to members
129 130 131 132 |
# File 'lib/philiprehberger/enum.rb', line 129 def members_by_value freeze_members! member_registry.each_value.to_h { |m| [m.value, m] } end |
.names ⇒ Array<Symbol>
Return all member names in declaration order
192 193 194 195 |
# File 'lib/philiprehberger/enum.rb', line 192 def names freeze_members! member_registry.keys.freeze end |
.sample(n = nil) ⇒ Enum+
Return a random member or array of random members
243 244 245 246 |
# File 'lib/philiprehberger/enum.rb', line 243 def sample(n = nil) freeze_members! n.nil? ? member_registry.values.sample : member_registry.values.sample(n) end |
.size ⇒ Integer Also known as: count
Return the number of defined members
137 138 139 140 |
# File 'lib/philiprehberger/enum.rb', line 137 def size freeze_members! member_registry.size end |
.slice(*names) ⇒ Array<Enum>
Return members matching the given symbol names, silently skipping unknown names
234 235 236 237 |
# File 'lib/philiprehberger/enum.rb', line 234 def slice(*names) freeze_members! names.filter_map { |n| member_registry[n.to_sym] } end |
.to_h ⇒ Hash{Symbol => Object}
Return a hash of name symbols to values
121 122 123 124 |
# File 'lib/philiprehberger/enum.rb', line 121 def to_h freeze_members! member_registry.transform_values(&:value) end |
.valid?(name) ⇒ Boolean
Check if a name is a valid member
225 226 227 228 |
# File 'lib/philiprehberger/enum.rb', line 225 def valid?(name) freeze_members! member_registry.key?(name.to_sym) end |
.values ⇒ Array<Object>
Return all member values in declaration order
200 201 202 203 |
# File 'lib/philiprehberger/enum.rb', line 200 def values freeze_members! member_registry.values.map(&:value).freeze end |
Instance Method Details
#<=>(other) ⇒ Integer?
Compare members by ordinal
45 46 47 48 49 |
# File 'lib/philiprehberger/enum.rb', line 45 def <=>(other) return nil unless other.is_a?(self.class) ordinal <=> other.ordinal end |
#deconstruct_keys(keys) ⇒ Hash
Support Ruby 3.x pattern matching with ‘in` expressions
72 73 74 75 |
# File 'lib/philiprehberger/enum.rb', line 72 def deconstruct_keys(keys) h = { name: name, ordinal: ordinal, value: value } keys ? h.slice(*keys) : h end |
#inspect ⇒ String
Returns a human-readable representation.
57 58 59 |
# File 'lib/philiprehberger/enum.rb', line 57 def inspect "#<#{self.class} #{name}>" end |
#to_json(*args) ⇒ String
Serialize to a JSON-compatible hash
64 65 66 |
# File 'lib/philiprehberger/enum.rb', line 64 def to_json(*args) { name: name, ordinal: ordinal, value: value }.to_json(*args) end |
#to_s ⇒ String
Returns the member name as a string.
52 53 54 |
# File 'lib/philiprehberger/enum.rb', line 52 def to_s name.to_s end |