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.0'
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<Symbols>
Defines new attributes.
-
.member?(name) ⇒ Boolean
Wheter 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. -
#inspect ⇒ String
(also: #to_s)
Description of itself as a string.
-
#member?(name) ⇒ Boolean
(also: #key?)
Wheter 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 atttributes 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.
260 261 262 |
# File 'lib/invariable.rb', line 260 def members @__attr__.keys end |
#size ⇒ Integer (readonly)
Returns number of attributes.
268 269 270 |
# File 'lib/invariable.rb', line 268 def size @__attr__.size end |
Class Method Details
.attributes(*names, **defaults) ⇒ Array<Symbols>
Defines new attributes
|
# File 'lib/invariable.rb', line 32
|
.member?(name) ⇒ Boolean
Returns wheter 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.
179 180 181 182 183 |
# File 'lib/invariable.rb', line 179 def dig(*identifiers) (Integer === identifiers.first ? @__attr__.values : @__attr__).dig( *identifiers ) end |
#each {|value| ... } ⇒ Invariable #each ⇒ Enumerator
197 198 199 200 201 |
# File 'lib/invariable.rb', line 197 def each(&block) return to_enum(__method__) unless block @__attr__.each_value(&block) self end |
#each_pair {|name, value| ... } ⇒ Invariable #each ⇒ Enumerator
216 217 218 219 220 |
# File 'lib/invariable.rb', line 216 def each_pair(&block) return to_enum(__method__) unless block @__attr__.each_pair(&block) self end |
#eql?(other) ⇒ Boolean
Compares its class and all attributes of itself with the class and attributes of a given other Object.
230 231 232 |
# File 'lib/invariable.rb', line 230 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 |
#inspect ⇒ String Also known as: to_s
Returns description of itself as a string.
242 243 244 245 |
# File 'lib/invariable.rb', line 242 def inspect attributes = @__attr__.map { |k, v| "#{k}: #{v.inspect}" } "<#{self.class}::#{__id__} #{attributes.join(', ')}>" end |
#member?(name) ⇒ Boolean Also known as: key?
Returns wheter the given name is a valid attribute name.
251 252 253 |
# File 'lib/invariable.rb', line 251 def member?(name) @__attr__.key?(name) end |
#to_a ⇒ Array<Object> Also known as: values
Returns the values of all attributes.
275 276 277 |
# File 'lib/invariable.rb', line 275 def to_a @__attr__.values end |
#to_h ⇒ Hash<Symbol,Object> #to_h(compact: true) ⇒ Hash<Symbol,Object> #to_h {|name, value| ... } ⇒ Hash<Object,Object>
302 303 304 305 306 |
# File 'lib/invariable.rb', line 302 def to_h(compact: false, &block) return to_compact_h if compact return Hash[@__attr__.map(&block)] if block @__attr__.transform_values { |v| v.is_a?(Invariable) ? v.to_h : v } end |
#update(attributes) ⇒ Invariable
Updates all given attributes.
312 313 314 315 316 317 318 |
# File 'lib/invariable.rb', line 312 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 atttributes of self at the given Integer indexes.
323 324 325 |
# File 'lib/invariable.rb', line 323 def values_at(...) @__attr__.values.values_at(...) end |