Module: Invariable
- Defined in:
- lib/invariable.rb,
lib/invariable/version.rb
Overview
An Invariable bundles a number of read-only attributes. It can be used like a Hash as well as an Array. It supports subclassing and pattern matching.
An Invariable can be created explicitly as a Class like a Struct. Or existing classes can easily be extended to an Invariable.
Constant Summary collapse
- VERSION =
current version number
'0.1.7'
Class Attribute Summary collapse
-
.members ⇒ Array<Symbol>
readonly
All attribute names of this class.
Instance Attribute Summary collapse
-
#members ⇒ Array<Symbol>
readonly
All attribute names.
-
#size ⇒ Integer
readonly
Number of attributes.
Class Method Summary collapse
-
.attributes(*names, **defaults) ⇒ Array<Symbol>
Defines new attributes.
-
.member?(name) ⇒ Boolean
Whether the given name is a valid attribute name for this class.
-
.new(*names, **defaults) {|new_class| ... } ⇒ Class
Creates a new class with the given attribute names.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
Compares attributes of itself with the attributes of a given other Object.
-
#[](arg) ⇒ Object
Returns the value of the given attribute or the attribute at the given index.
-
#dig(*identifiers) ⇒ Object?
Finds and returns the object in nested objects that is specified by the identifiers.
- #each(&block) ⇒ Object
- #each_pair(&block) ⇒ Object
-
#eql?(other) ⇒ Boolean
Compares its class and all attributes of itself with the class and attributes of a given other Object.
-
#initialize(attributes = nil) ⇒ Invariable
Initializes a new instance with the given
attributes
Hash. -
#member?(name) ⇒ Boolean
(also: #key?)
Whether the given name is a valid attribute name.
-
#to_a ⇒ Array<Object>
(also: #values)
The values of all attributes.
- #to_h(compact: false, &block) ⇒ Object
-
#update(attributes) ⇒ Invariable
Updates all given attributes.
-
#values_at ⇒ Array<Object>
Array whose elements are the attributes of self at the given Integer indexes.
Class Attribute Details
.members ⇒ Array<Symbol> (readonly)
Returns all attribute names of this class.
|
# File 'lib/invariable.rb', line 32
|
Instance Attribute Details
#members ⇒ Array<Symbol> (readonly)
Returns all attribute names.
261 262 263 |
# File 'lib/invariable.rb', line 261 def members @__attr__.keys end |
#size ⇒ Integer (readonly)
Returns number of attributes.
269 270 271 |
# File 'lib/invariable.rb', line 269 def size @__attr__.size end |
Class Method Details
.attributes(*names, **defaults) ⇒ Array<Symbol>
Defines new attributes
|
# File 'lib/invariable.rb', line 32
|
.member?(name) ⇒ Boolean
Returns whether the given name is a valid attribute name for this class.
|
# File 'lib/invariable.rb', line 32
|
.new(*names, **defaults, &block) ⇒ Class .new(base_class, *names, **defaults, &block) ⇒ Class
Creates a new class with the given attribute names. It also allows to specify default values which are used when an instance is created.
With an optional block the class can be extended.
86 87 88 89 90 91 92 |
# File 'lib/invariable.rb', line 86 def new(*names, **defaults, &block) Class.new(names.first.is_a?(Class) ? names.shift : Object) do include(Invariable) attributes(*names, **defaults) class_eval(&block) if block end end |
Instance Method Details
#==(other) ⇒ Boolean
Compares attributes of itself with the attributes of a given other Object.
This means that the given object needs to implement the same attributes and all it's attribute values have to be equal.
133 134 135 136 137 138 |
# File 'lib/invariable.rb', line 133 def ==(other) @__attr__.each_pair do |k, v| return false if !other.respond_to?(k) || (v != other.__send__(k)) end true end |
#[](name) ⇒ Object #[](index) ⇒ Object
Returns the value of the given attribute or the attribute at the given index.
155 156 157 158 159 160 161 162 |
# File 'lib/invariable.rb', line 155 def [](arg) return @__attr__[arg] if @__attr__.key?(arg) raise(NameError, "not member - #{arg}", caller) unless Integer === arg if arg >= @__attr__.size || arg < -@__attr__.size raise(IndexError, "invalid offset - #{arg}") end @__attr__.values[arg] end |
#dig(*identifiers) ⇒ Object?
Finds and returns the object in nested objects that is specified by the identifiers. The nested objects may be instances of various classes.
184 185 186 187 188 |
# File 'lib/invariable.rb', line 184 def dig(*identifiers) (Integer === identifiers.first ? @__attr__.values : @__attr__).dig( *identifiers ) end |
#each {|value| ... } ⇒ Invariable #each ⇒ Enumerator
202 203 204 |
# File 'lib/invariable.rb', line 202 def each(&block) block ? @__attr__.each_value(&block) : to_enum(__method__) end |
#each_pair {|name, value| ... } ⇒ Invariable #each ⇒ Enumerator
219 220 221 |
# File 'lib/invariable.rb', line 219 def each_pair(&block) block ? @__attr__.each_pair(&block) : to_enum(__method__) end |
#eql?(other) ⇒ Boolean
Compares its class and all attributes of itself with the class and attributes of a given other Object.
231 232 233 |
# File 'lib/invariable.rb', line 231 def eql?(other) self.class == other.class && self == other end |
#initialize(attributes = nil) ⇒ Invariable
Initializes a new instance with the given attributes
Hash.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/invariable.rb', line 106 def initialize(attributes = nil) super() attributes ||= {}.compare_by_identity @__attr__ = {} self .class .instance_variable_get(:@__attr__) .each_pair do |key, default| @__attr__[key] = if default.is_a?(Class) default.new(attributes[key]).freeze elsif attributes.key?(key) attributes[key] else default end end end |
#member?(name) ⇒ Boolean Also known as: key?
Returns whether the given name is a valid attribute name.
252 253 254 |
# File 'lib/invariable.rb', line 252 def member?(name) @__attr__.key?(name) end |
#to_a ⇒ Array<Object> Also known as: values
Returns the values of all attributes.
276 277 278 |
# File 'lib/invariable.rb', line 276 def to_a @__attr__.values end |
#to_h ⇒ {Symbol => Object} #to_h(compact: true) ⇒ {Symbol => Object} #to_h {|name, value| ... } ⇒ {Object => Object}
298 299 300 301 302 |
# File 'lib/invariable.rb', line 298 def to_h(compact: false, &block) return Hash[@__attr__.map(&block)] if block return __to_compact_h if compact @__attr__.transform_values { |v| v.is_a?(Invariable) ? v.to_h : v } end |
#update(attributes) ⇒ Invariable
Updates all given attributes.
308 309 310 311 312 313 314 |
# File 'lib/invariable.rb', line 308 def update(attributes) opts = {} @__attr__.each_pair do |k, v| opts[k] = attributes.key?(k) ? attributes[k] : v end self.class.new(opts) end |
#values_at ⇒ Array<Object>
Returns Array whose elements are the attributes of self at the given Integer indexes.
319 320 321 |
# File 'lib/invariable.rb', line 319 def values_at(...) @__attr__.values.values_at(...) end |