Class: Myrrha::Coercions
Overview
Defines a set of coercion rules
Instance Attribute Summary collapse
-
#error_handler ⇒ Proc
The proc that handles coercion errors.
-
#main_target_domain ⇒ Domain
The main target domain, if any.
Instance Method Summary collapse
-
#append(&proc) ⇒ Object
Appends the list of rules with new ones.
-
#coerce(value, target_domain = main_target_domain) ⇒ Object
(also: #apply)
Coerces ‘value` to an element of `target_domain`.
-
#coercion(source, target = main_target_domain, converter = nil, &convproc) ⇒ Object
Adds a coercion rule from a source to a target domain.
-
#delegate(method, &convproc) ⇒ Object
Adds an upon rule that works by delegation if the value responds to ‘method`.
-
#dup ⇒ Coercions
Duplicates this set of rules in such a way that the original will not be affected by any change made to the copy.
-
#fallback(source, converter = nil, &convproc) ⇒ Object
Adds a fallback rule for a source domain.
-
#initialize(&defn) ⇒ Coercions
constructor
Creates an empty list of coercion rules.
-
#prepend(&proc) ⇒ Object
Prepends the list of rules with new ones.
-
#upon(source, converter = nil, &convproc) ⇒ Object
Adds an upon rule for a source domain.
Constructor Details
#initialize(&defn) ⇒ Coercions
Creates an empty list of coercion rules
13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/myrrha/coercions.rb', line 13 def initialize(&defn) @definitions = [] @upons = [] @rules = [] @fallbacks = [] @appender = :<< @main_target_domain = nil @error_handler = lambda{|value, target_domain, cause| raise Error.new("Unable to coerce `#{value}` to #{target_domain}", cause) } extend_rules(:<<, defn) if defn end |
Instance Attribute Details
#error_handler ⇒ Proc
Returns the proc that handles coercion errors.
10 11 12 |
# File 'lib/myrrha/coercions.rb', line 10 def error_handler @error_handler end |
#main_target_domain ⇒ Domain
Returns The main target domain, if any.
7 8 9 |
# File 'lib/myrrha/coercions.rb', line 7 def main_target_domain @main_target_domain end |
Instance Method Details
#append(&proc) ⇒ Object
Appends the list of rules with new ones.
New upon, coercion and fallback rules will be put after the already existing ones, in each case.
Example:
rules = Myrrha.coercions do ... end
rules.append do |r|
# [previous coercion rules would come here]
# install new rules
r.coercion String, Float, lambda{|v,t| Float(t)}
end
42 43 44 |
# File 'lib/myrrha/coercions.rb', line 42 def append(&proc) extend_rules(:<<, proc) end |
#coerce(value, target_domain = main_target_domain) ⇒ Object Also known as: apply
Coerces ‘value` to an element of `target_domain`
This method tries each coercion rule, then each fallback in turn. Rules for which source and target domain match are executed until one succeeds. A Myrrha::Error is raised if no rule matches or executes successfuly.
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/myrrha/coercions.rb', line 170 def coerce(value, target_domain = main_target_domain) return value if belongs_to?(value, target_domain) error = nil each_rule do |from,to,converter| next unless from.nil? or belongs_to?(value, from, target_domain) begin catch(:nextrule) do if to.nil? or subdomain?(to, target_domain) got = convert(value, target_domain, converter) return got elsif subdomain?(target_domain, to) got = convert(value, target_domain, converter) return got if belongs_to?(got, target_domain) end end rescue => ex error = ex unless error end end error_handler.call(value, target_domain, error) end |
#coercion(source, target = main_target_domain, converter = nil, &convproc) ⇒ Object
Adds a coercion rule from a source to a target domain.
The conversion can be provided through ‘converter` or via a block directly. See main documentation about recognized converters.
Example:
Myrrha.coercions do |r|
# With an explicit proc
r.coercion String, Integer, lambda{|v,t|
Integer(v)
}
# With an implicit proc
r.coercion(String, Float) do |v,t|
Float(v)
end
end
132 133 134 135 |
# File 'lib/myrrha/coercions.rb', line 132 def coercion(source, target = main_target_domain, converter = nil, &convproc) @rules.send(@appender, [source, target, converter || convproc]) self end |
#delegate(method, &convproc) ⇒ Object
100 101 102 103 |
# File 'lib/myrrha/coercions.rb', line 100 def delegate(method, &convproc) convproc ||= lambda{|v,t| v.send(method) } upon(lambda{|v,t| v.respond_to?(method) }, convproc) end |
#dup ⇒ Coercions
Duplicates this set of rules in such a way that the original will not be affected by any change made to the copy.
198 199 200 201 202 203 204 |
# File 'lib/myrrha/coercions.rb', line 198 def dup c = Coercions.new @definitions.each do |defn| c.extend_rules(*defn) end c end |
#fallback(source, converter = nil, &convproc) ⇒ Object
155 156 157 158 |
# File 'lib/myrrha/coercions.rb', line 155 def fallback(source, converter = nil, &convproc) @fallbacks.send(@appender, [source, nil, converter || convproc]) self end |
#prepend(&proc) ⇒ Object
Prepends the list of rules with new ones.
New upon, coercion and fallback rules will be put before the already existing ones, in each case.
Example:
rules = Myrrha.coercions do ... end
rules.prepend do |r|
# install new rules
r.coercion String, Float, lambda{|v,t| Float(t)}
# [previous coercion rules would come here]
end
63 64 65 |
# File 'lib/myrrha/coercions.rb', line 63 def prepend(&proc) extend_rules(:unshift, proc) end |
#upon(source, converter = nil, &convproc) ⇒ Object
Adds an upon rule for a source domain.
Example:
Myrrha.coercions do |r|
# Don't even try something else on nil
r.upon(NilClass){|s,t| nil}
[...]
end
84 85 86 87 |
# File 'lib/myrrha/coercions.rb', line 84 def upon(source, converter = nil, &convproc) @upons.send(@appender, [source, nil, converter || convproc]) self end |