Class: Redmine::Value
- Inherits:
-
Object
- Object
- Redmine::Value
- Defined in:
- lib/redmine/value.rb
Overview
Base class for immutable value objects.
Value objects with the same attributes are considered equal. Value objects cannot be modified, but new values can be constructed by applying new attribute values to existing values.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#hash ⇒ Object
readonly
Returns the value of attribute hash.
Class Method Summary collapse
-
.attribute(name, type: nil, path: nil) ⇒ nil
Define a new attribute for this value.
-
.attributes ⇒ Object
List of all known attributes supported by this Value.
-
.parse_value(value, type = nil) ⇒ Object
Value parsed to ‘type`.
Instance Method Summary collapse
- #eql?(other) ⇒ Bool (also: #==)
-
#initialize(attrs = {}) ⇒ Value
constructor
A new instance of Value.
- #to_a ⇒ Array
- #to_h ⇒ Hash
-
#with(attrs = {}) ⇒ Value
Create a new value based on the current value, but with the incoming attributes assigned.
Constructor Details
#initialize(attrs = {}) ⇒ Value
Returns a new instance of Value.
53 54 55 56 57 58 59 |
# File 'lib/redmine/value.rb', line 53 def initialize(attrs = {}) attrs.to_h.each do |name, value| send(:"#{name}=", value) end @hash = self.class.hash ^ to_a.hash freeze end |
Instance Attribute Details
#hash ⇒ Object (readonly)
Returns the value of attribute hash.
8 9 10 |
# File 'lib/redmine/value.rb', line 8 def hash @hash end |
Class Method Details
.attribute(name, type: nil, path: nil) ⇒ nil
Define a new attribute for this value. Attributes can be casted into a specific type, and can optionally be read from a path inside a nested structure (see Rubys ‘dig` method).
38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/redmine/value.rb', line 38 def self.attribute(name, type: nil, path: nil) attributes << name.to_sym attr_reader name define_method :"#{name}=" do |value| value = value.dig(*Array(path)) if path && value.respond_to?(:dig) parsed_value = self.class.parse_value(value, type) instance_variable_set(:"@#{name}", parsed_value) end private :"#{name}=" nil end |
.attributes ⇒ Object
List of all known attributes supported by this Value.
11 12 13 |
# File 'lib/redmine/value.rb', line 11 def self.attributes @attributes ||= [] end |
.parse_value(value, type = nil) ⇒ Object
Returns value parsed to ‘type`.
18 19 20 21 22 23 24 25 26 27 |
# File 'lib/redmine/value.rb', line 18 def self.parse_value(value, type = nil) case type when ->(t) { t.nil? } then value when ->(t) { t === value } then value when ->(t) { t.respond_to?(:parse) } then type.parse(value) when ->(t) { Kernel.respond_to?(t.to_s) } Kernel.send(type.to_s, value) else raise ArgumentError, "Invalid type #{type.inspect}" end end |
Instance Method Details
#eql?(other) ⇒ Bool Also known as: ==
73 74 75 |
# File 'lib/redmine/value.rb', line 73 def eql?(other) hash == other.hash end |
#to_a ⇒ Array
84 85 86 |
# File 'lib/redmine/value.rb', line 84 def to_a self.class.attributes.map { |attr| [attr, send(attr)] } end |
#to_h ⇒ Hash
79 80 81 |
# File 'lib/redmine/value.rb', line 79 def to_h Hash[to_a] end |
#with(attrs = {}) ⇒ Value
Create a new value based on the current value, but with the incoming attributes assigned. This “changes” the value, but leaves the original value intact – as you’ll get a new instance instead.
68 69 70 |
# File 'lib/redmine/value.rb', line 68 def with(attrs = {}) self.class.new(to_h.merge(attrs)) end |