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, Class, Date, DateTime, Float, Hash, Integer, Nil, Object, 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.
85 86 87 88 89 90 91 92 |
# File 'lib/mixture/coerce/base.rb', line 85 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.
33 34 35 |
# File 'lib/mixture/coerce/base.rb', line 33 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.
103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/mixture/coerce/base.rb', line 103 def self.data_block(data, &block) case when data.is_a?(::Symbol) proc { |value| value.public_send(data) } when data.is_a?(::Proc) data when 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.
43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/mixture/coerce/base.rb', line 43 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 |
# File 'lib/mixture/coerce/base.rb', line 127 def to(type) coercions = self.class.coercions coercable = type.inheritable .find { |ancestor| coercions.key?(ancestor) } fail CoercionError, "Undefined coercion #{self.class.type} " \ "=> #{type}" unless coercable public_send(coercions[coercable]) end |