Class: MetaEnum::Type
- Inherits:
-
Object
- Object
- MetaEnum::Type
- Defined in:
- lib/meta_enum/type.rb
Instance Attribute Summary collapse
-
#elements ⇒ Object
readonly
Returns the value of attribute elements.
-
#elements_by_name ⇒ Object
readonly
Returns the value of attribute elements_by_name.
-
#elements_by_value ⇒ Object
readonly
Returns the value of attribute elements_by_value.
Instance Method Summary collapse
-
#[](key) ⇒ Object
-
is a “do what I mean” operator.
-
-
#initialize(elements, value_normalizer: method(:Integer), element_class: MetaEnum::Element) ⇒ Type
constructor
Initialize takes a single hash of name to value.
- #inspect ⇒ Object
- #size ⇒ Object
Constructor Details
#initialize(elements, value_normalizer: method(:Integer), element_class: MetaEnum::Element) ⇒ Type
Initialize takes a single hash of name to value.
e.g. MetaEnum::Type.new(red: 0, green: 1, blue: 2)
Additional data can also be associated with each value by passing an array of [value, extra data]. This can be used for additional description or any other reason.
e.g. MetaEnum::Type.new(small: [0, “Less than 10], large: [1, ”At least 10“]
value_normalizer is a callable object that normalizes values. The default converts all values to integers. To allow string values use method(:String).
element_class is the class with which to create elements. It should be a sub-class of MetaEnum::Element (or otherwise match it’s behavior).
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/meta_enum/type.rb', line 37 def initialize( elements, value_normalizer: method(:Integer), element_class: MetaEnum::Element ) @value_normalizer = value_normalizer @elements_by_value = {} @elements_by_name = {} @elements = Set.new elements.each do |name, value_and_data| value_and_data = Array(value_and_data) v = element_class.new normalize_value(value_and_data[0]), name, value_and_data[1], self raise ArgumentError, "duplicate value: #{v.value}" if @elements_by_value.key? v.value raise ArgumentError, "duplicate name: #{v.name}" if @elements_by_name.key? v.name @elements_by_value[v.value] = v @elements_by_name[v.name] = v @elements.add(v) end @elements_by_value.freeze @elements_by_name.freeze @elements.freeze freeze end |
Instance Attribute Details
#elements ⇒ Object (readonly)
Returns the value of attribute elements.
20 21 22 |
# File 'lib/meta_enum/type.rb', line 20 def elements @elements end |
#elements_by_name ⇒ Object (readonly)
Returns the value of attribute elements_by_name.
20 21 22 |
# File 'lib/meta_enum/type.rb', line 20 def elements_by_name @elements_by_name end |
#elements_by_value ⇒ Object (readonly)
Returns the value of attribute elements_by_value.
20 21 22 |
# File 'lib/meta_enum/type.rb', line 20 def elements_by_value @elements_by_value end |
Instance Method Details
#[](key) ⇒ Object
-
is a “do what I mean” operator. It returns the Element from this type depending on the key.
When key is a symbol, it is considered the name of the Element to return. Since symbols are used from code, it is considered an error if the key is not found and it raises an exception.
When key can be converted to an integer by value_normalizer, then it is considered the value of the Element to return. Retrieving by value is presumed to converting from external data where a missing value should not be considered fatal. In this case it returns a MissingElement is with value as the key. This allows a Type to only specify the values it needs while passing through the others unmodified.
Finally, when key is a MetaEnum::Element, it is simply returned (unless it belongs to a different Type in which case an ArgumentError is raised).
See #values_by_number and #values_by_name for non-fuzzy value selection.
80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/meta_enum/type.rb', line 80 def [](key) case key when Element, MissingElement raise ArgumentError, "wrong type" unless key.type == self key when Symbol elements_by_name.fetch(key) else key = normalize_value(key) elements_by_value.fetch(key) { MissingElement.new key, self } end end |
#inspect ⇒ Object
93 94 95 |
# File 'lib/meta_enum/type.rb', line 93 def inspect sprintf('#<%s: {%s}>', self.class, elements.to_a.map { |v| "#{v.name}: #{v.value}"}.join(", ")) end |
#size ⇒ Object
97 98 99 |
# File 'lib/meta_enum/type.rb', line 97 def size elements.size end |