class ValueSemantics::Attribute
Represents a single attribute of a value class
Constants
- NOT_SPECIFIED
- NO_DEFAULT_GENERATOR
Attributes
coercer[R]
default_generator[R]
instance_variable[R]
name[R]
optional[R]
optional?[R]
validator[R]
Public Class Methods
define( name, validator=Anything, default: NOT_SPECIFIED, default_generator: nil, coerce: nil )
click to toggle source
# 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
new( name:, default_generator: NO_DEFAULT_GENERATOR, validator: Anything, coercer: nil )
click to toggle source
# 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
Public Instance Methods
coerce(attr_value, value_class)
click to toggle source
# 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()
click to toggle source
# File lib/value_semantics/attribute.rb, line 96 def coercion_method "coerce_#{name}" end
determine_from!(attr_hash, value_class)
click to toggle source
@deprecated Use a combination of the other instance methods instead
# 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)
click to toggle source
# File lib/value_semantics/attribute.rb, line 92 def validate?(value) validator === value end