Class: Mixture::Coerce::Base
- Inherits:
-
Object
- Object
- Mixture::Coerce::Base
- Includes:
- Singleton
- Defined in:
- lib/mixture/coerce/base.rb
Overview
The base for coercion actions. Each action defines the "from" type, and the instance handles the "to".
Direct Known Subclasses
Array, Boolean, Class, Date, DateTime, Float, Hash, Integer, Nil, Object, Range, Rational, Set, String, Symbol, Time
Class Method Summary collapse
-
.coerce_to(to, data = Undefined, &block) ⇒ Object
This is a DSL for the class itself.
-
.coercions ⇒ Hash{Mixture::Type => Symbol}
The coercions that this class has.
-
.data_block(data, &block) ⇒ void
Turns a data/block given to Base.coerce_to into a block worthy of a body for a method.
-
.inherited(base) ⇒ void
This is a method that's called by ruby interally.
-
.to(type) ⇒ Proc{(Object) => Object}
Returns a block to perform the coercion to the given type.
- .type(value = Undefined) ⇒ Object
Instance Method Summary collapse
-
#to(type) ⇒ Proc{(Object) => Object}
Returns a block to perform the coercion to the given type.
Class Method Details
.coerce_to(to) {|value, type| ... } ⇒ void .coerce_to(to, value) ⇒ void
This is a DSL for the class itself. It essentially defines a method to perform the coercion of the given type.
86 87 88 89 90 91 92 93 |
# File 'lib/mixture/coerce/base.rb', line 86 def self.coerce_to(to, data = Undefined, &block) fail ArgumentError, "Expected Mixture::Types::Type, got #{to}" unless to <= Mixture::Types::Type body = data_block(data, &block) coercions[to] = to.[:method] define_method(to.[:method]) { body } end |
.coercions ⇒ Hash{Mixture::Type => Symbol}
The coercions that this class has. It's a map of the type to the method that performs that coercion.
34 35 36 |
# File 'lib/mixture/coerce/base.rb', line 34 def self.coercions @_coercions ||= ThreadSafe::Hash.new end |
.data_block(data, &block) ⇒ void
This method returns an undefined value.
Turns a data/block given to coerce_to into a block worthy of a body for a method.
104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/mixture/coerce/base.rb', line 104 def self.data_block(data, &block) if data.is_a?(::Symbol) proc { |value| value.public_send(data) } elsif data.is_a?(::Proc) data elsif block_given? block else fail ArgumentError, "Expected a block, got #{data.inspect}" end end |
.inherited(base) ⇒ void
This method returns an undefined value.
This is a method that's called by ruby interally. We're going to use it to hook into the coercions, to allow a class coercion.
44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/mixture/coerce/base.rb', line 44 def self.inherited(base) super # for Singleton base.coerce_to(Types::Class) do |value, type| member = type..fetch(:members).first if member.respond_to?(:coerce) then member.coerce(value) elsif member.respond_to?(:new) then member.new(value) else fail CoercionError, "Expected #{member} to " \ "respond to #coerce, #new" end end end |
.to(type) ⇒ Proc{(Object) => Object}
Returns a block to perform the coercion to the given type. If it cannot find a coercion, it raises Mixture::CoercionError.
117 118 119 |
# File 'lib/mixture/coerce/base.rb', line 117 def self.to(type) instance.to(type) end |
Instance Method Details
#to(type) ⇒ Proc{(Object) => Object}
Returns a block to perform the coercion to the given type. If it cannot find a coercion, it raises Mixture::CoercionError.
127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/mixture/coerce/base.rb', line 127 def to(type) coercions = self.class.coercions coercable = type.inheritable .find { |ancestor| coercions.key?(ancestor) } unless coercable fail CoercionError, "Undefined coercion #{self.class.type} " \ "=> #{type}" end public_send(coercions[coercable]) end |