Class: ValueSemantics::Attribute
- Inherits:
-
Object
- Object
- ValueSemantics::Attribute
- Defined in:
- lib/value_semantics/attribute.rb
Overview
Represents a single attribute of a value class
Constant Summary collapse
- NOT_SPECIFIED =
Object.new.freeze
- NO_DEFAULT_GENERATOR =
lambda do raise NoDefaultValue, "Attribute does not have a default value" end
Instance Attribute Summary collapse
-
#coercer ⇒ Object
readonly
Returns the value of attribute coercer.
-
#default_generator ⇒ Object
readonly
Returns the value of attribute default_generator.
-
#instance_variable ⇒ Object
readonly
Returns the value of attribute instance_variable.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#optional ⇒ Object
(also: #optional?)
readonly
Returns the value of attribute optional.
-
#validator ⇒ Object
readonly
Returns the value of attribute validator.
Class Method Summary collapse
Instance Method Summary collapse
- #coerce(attr_value, value_class) ⇒ Object
- #coercion_method ⇒ Object
-
#determine_from!(attr_hash, value_class) ⇒ Object
deprecated
Deprecated.
Use a combination of the other instance methods instead
-
#initialize(name:, default_generator: NO_DEFAULT_GENERATOR, validator: Anything, coercer: nil) ⇒ Attribute
constructor
A new instance of Attribute.
- #validate?(value) ⇒ Boolean
Constructor Details
#initialize(name:, default_generator: NO_DEFAULT_GENERATOR, validator: Anything, coercer: nil) ⇒ Attribute
Returns a new instance of Attribute.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/value_semantics/attribute.rb', line 15 def initialize( name:, default_generator: NO_DEFAULT_GENERATOR, validator: Anything, coercer: nil ) @name = name.to_sym @default_generator = default_generator @validator = validator @coercer = coercer @instance_variable = '@' + name.to_s.chomp('!').chomp('?') @optional = !default_generator.equal?(NO_DEFAULT_GENERATOR) freeze end |
Instance Attribute Details
#coercer ⇒ Object (readonly)
Returns the value of attribute coercer.
11 12 13 |
# File 'lib/value_semantics/attribute.rb', line 11 def coercer @coercer end |
#default_generator ⇒ Object (readonly)
Returns the value of attribute default_generator.
11 12 13 |
# File 'lib/value_semantics/attribute.rb', line 11 def default_generator @default_generator end |
#instance_variable ⇒ Object (readonly)
Returns the value of attribute instance_variable.
11 12 13 |
# File 'lib/value_semantics/attribute.rb', line 11 def instance_variable @instance_variable end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
11 12 13 |
# File 'lib/value_semantics/attribute.rb', line 11 def name @name end |
#optional ⇒ Object (readonly) Also known as: optional?
Returns the value of attribute optional.
11 12 13 |
# File 'lib/value_semantics/attribute.rb', line 11 def optional @optional end |
#validator ⇒ Object (readonly)
Returns the value of attribute validator.
11 12 13 |
# File 'lib/value_semantics/attribute.rb', line 11 def validator @validator end |
Class Method Details
.define(name, validator = Anything, default: NOT_SPECIFIED, default_generator: nil, coerce: nil) ⇒ Object
30 31 32 33 34 35 36 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 62 |
# File 'lib/value_semantics/attribute.rb', line 30 def self.define( name, validator=Anything, default: NOT_SPECIFIED, default_generator: nil, coerce: nil ) # TODO: change how defaults are specified: # # - default: either a value, or a callable # - default_value: always a value # - default_generator: always a callable # # This would not be a backwards compatible change. generator = begin if default_generator && !default.equal?(NOT_SPECIFIED) raise ArgumentError, "Attribute `#{name}` can not have both a `:default` and a `:default_generator`" elsif default_generator default_generator elsif !default.equal?(NOT_SPECIFIED) ->{ default } else NO_DEFAULT_GENERATOR end end new( name: name, validator: validator, default_generator: generator, coercer: coerce, ) end |
Instance Method Details
#coerce(attr_value, value_class) ⇒ Object
82 83 84 85 86 87 88 89 90 |
# File 'lib/value_semantics/attribute.rb', line 82 def coerce(attr_value, value_class) return attr_value unless coercer # coercion not enabled if coercer.equal?(true) value_class.public_send(coercion_method, attr_value) else coercer.call(attr_value) end end |
#coercion_method ⇒ Object
96 97 98 |
# File 'lib/value_semantics/attribute.rb', line 96 def coercion_method "coerce_#{name}" end |
#determine_from!(attr_hash, value_class) ⇒ Object
Deprecated.
Use a combination of the other instance methods instead
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/value_semantics/attribute.rb', line 65 def determine_from!(attr_hash, value_class) raw_value = attr_hash.fetch(name) do if default_generator.equal?(NO_DEFAULT_GENERATOR) raise MissingAttributes, "Attribute `#{value_class}\##{name}` has no value" else default_generator.call end end coerced_value = coerce(raw_value, value_class) if validate?(coerced_value) [name, coerced_value] else raise InvalidValue, "Attribute `#{value_class}\##{name}` is invalid: #{coerced_value.inspect}" end end |
#validate?(value) ⇒ Boolean
92 93 94 |
# File 'lib/value_semantics/attribute.rb', line 92 def validate?(value) validator === value end |