Class: Enumancer::Enum

Inherits:
Object
  • Object
show all
Defined in:
lib/enum.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value) ⇒ Enum

Returns a new instance of Enum.



38
39
40
# File 'lib/enum.rb', line 38

def initialize(value)
  @value = value
end

Instance Attribute Details

#valueObject (readonly)

Returns the value of attribute value.



36
37
38
# File 'lib/enum.rb', line 36

def value
  @value
end

Class Method Details

.[](name) ⇒ Enumancer::Enum?

Retrieves an enum instance by name

Parameters:

  • name (Symbol, String)

Returns:



148
149
150
# File 'lib/enum.rb', line 148

def [](name)
  @registry[name.to_sym]
end

.allArray<Enumancer::Enum>

Returns all registered enum instances

Returns:



172
173
174
# File 'lib/enum.rb', line 172

def all
  @registry.values
end

.entry(name, value) ⇒ void

This method returns an undefined value.

Registers a new enum entry with a unique name and value

Parameters:

  • name (Symbol, String)

    symbolic name of the entry

  • value (Object)

    value of the entry

Raises:

  • (ArgumentError)

    if name or value is already registered

  • (TypeError)

    if value does not match declared type



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/enum.rb', line 121

def entry(name, value)
  name = name.to_sym

  if defined?(@value_type) && !value.is_a?(@value_type)
    raise TypeError, "Invalid value type for #{name}: expected #{@value_type}, got #{value.class}"
  end

  if @values.key?(value)
    existing = @values[value]
    raise ArgumentError, "Duplicate value #{value.inspect} for #{name}; already assigned to #{existing}"
  end

  if @registry.key?(name)
    raise ArgumentError, "Duplicate name #{name}; already registered with value #{@registry[name].value.inspect}"
  end

  instance = new(value)
  @registry[name] = instance
  @values[value] = name

  define_singleton_method(name) { instance }
end

.fetch(name) ⇒ Enumancer::Enum

Retrieves an enum instance by name, raising if not found

Parameters:

  • name (Symbol, String)

Returns:

Raises:

  • (KeyError)


157
158
159
# File 'lib/enum.rb', line 157

def fetch(name)
  @registry.fetch(name.to_sym)
end

.from_json(json) ⇒ Enumancer::Enum?

Deserializes an enum from JSON

Parameters:

  • json (String)

Returns:

Raises:

  • (KeyError)

    if strict and name is unknown



209
210
211
212
213
214
215
216
217
218
219
# File 'lib/enum.rb', line 209

def from_json(json)
  data = JSON.parse(json, symbolize_names: true)
  name = data[:name]
  raise KeyError, "Missing 'name' key in JSON" if name.nil?

  entry = self[name]
  if strict? && entry.nil?
    raise KeyError, "Unregistered enum name: #{name.inspect}"
  end
  entry
end

.inherited(subclass) ⇒ void

This method returns an undefined value.

Called when subclassing Enum

Parameters:

  • subclass (Class)


88
89
90
91
92
# File 'lib/enum.rb', line 88

def inherited(subclass)
  subclass.instance_variable_set(:@registry, {})
  subclass.instance_variable_set(:@values, {})
  subclass.instance_variable_set(:@strict_mode, false)
end

.keysArray<Symbol>

Returns all registered names

Returns:

  • (Array<Symbol>)


179
180
181
# File 'lib/enum.rb', line 179

def keys
  @registry.keys
end

.name_for(value) ⇒ Symbol?

Resolves the symbolic name for a given value

Parameters:

  • value (Object)

Returns:

  • (Symbol, nil)


165
166
167
# File 'lib/enum.rb', line 165

def name_for(value)
  @values[value]
end

.remove(name) ⇒ Enumancer::Enum?

Removes an enum entry by name

Parameters:

  • name (Symbol, String)

Returns:



194
195
196
197
198
199
200
201
202
# File 'lib/enum.rb', line 194

def remove(name)
  name = name.to_sym
  entry = @registry.delete(name)
  if entry
    @values.delete(entry.value)
    singleton_class.undef_method(name) if respond_to?(name)
  end
  entry
end

.strict?Boolean

Returns whether strict mode is enabled

Returns:

  • (Boolean)


110
111
112
# File 'lib/enum.rb', line 110

def strict?
  @strict_mode == true
end

.type(klass, strict: false) ⇒ void

This method returns an undefined value.

Declares the expected type of all enum values

Parameters:

  • klass (Class)

    the type constraint for values

  • strict (Boolean) (defaults to: false)

    whether to enable strict mode



99
100
101
102
103
104
105
# File 'lib/enum.rb', line 99

def type(klass, strict: false)
  unless klass.is_a?(Class)
    raise ArgumentError, "Expected a Class, got #{klass.inspect}"
  end
  @value_type = klass
  @strict_mode = strict
end

.valuesArray<Object>

Returns all raw values

Returns:

  • (Array<Object>)


186
187
188
# File 'lib/enum.rb', line 186

def values
  @registry.values.map(&:value)
end

Instance Method Details

#==(other) ⇒ Boolean Also known as: eql?

Equality based on class and value

Parameters:

  • other (Object)

Returns:

  • (Boolean)


69
70
71
# File 'lib/enum.rb', line 69

def ==(other)
  other.is_a?(self.class) && other.value == value
end

#hashObject



74
# File 'lib/enum.rb', line 74

def hash = value.hash

#inspectString

Returns a debug-friendly string representation

Returns:

  • (String)


61
62
63
# File 'lib/enum.rb', line 61

def inspect
  "#<#{self.class.name} #{to_sym.inspect}:#{value.inspect}>"
end

#to_json(*args) ⇒ String

Serializes the enum to JSON

Returns:

  • (String)


79
80
81
# File 'lib/enum.rb', line 79

def to_json(*args)
  { name: to_sym, value: value }.to_json(*args)
end

#to_sString

Returns the symbolic name of the value as a string

Returns:

  • (String)


45
46
47
# File 'lib/enum.rb', line 45

def to_s
  to_sym.to_s
end

#to_symSymbol

Returns the symbolic name of the value as a symbol

Returns:

  • (Symbol)

Raises:

  • (KeyError)


52
53
54
55
56
# File 'lib/enum.rb', line 52

def to_sym
  name = self.class.name_for(value)
  raise KeyError, "Unregistered enum value: #{value.inspect}" if name.nil? && self.class.strict?
  name || :unknown
end