module Hashie::Extensions::Coercion::InstanceMethods
def coerce_or_init(type)
def coerce_or_init(type) return type if type.is_a? Proc if CORE_TYPES.key?(type) lambda do |v| return v if v.is_a? type return v.send(CORE_TYPES[type]) end elsif type.respond_to?(:coerce) lambda do |v| return v if v.is_a? type type.coerce(v) end elsif type.respond_to?(:new) lambda do |v| return v if v.is_a? type type.new(v) end else fail TypeError, "#{type} is not a coercable type" end end
def custom_writer(key, value, _convert = true)
def custom_writer(key, value, _convert = true) self[key] = value end
def replace(other_hash)
def replace(other_hash) (keys - other_hash.keys).each { |key| delete(key) } other_hash.each { |key, value| self[key] = value } self end
def set_value_with_coercion(key, value)
def set_value_with_coercion(key, value) into = self.class.key_coercion(key) || self.class.value_coercion(value) return set_value_without_coercion(key, value) if value.nil? || into.nil? begin return set_value_without_coercion(key, coerce_or_init(into).call(value)) unless into.is_a?(Enumerable) if into.class <= ::Hash key_coerce = coerce_or_init(into.flatten[0]) value_coerce = coerce_or_init(into.flatten[-1]) value = into.class[value.map { |k, v| [key_coerce.call(k), value_coerce.call(v)] }] else # Enumerable but not Hash: Array, Set value_coerce = coerce_or_init(into.first) value = into.class.new(value.map { |v| value_coerce.call(v) }) end rescue NoMethodError, TypeError => e raise CoercionError, "Cannot coerce property #{key.inspect} from #{value.class} to #{into}: #{e.message}" end set_value_without_coercion(key, value) end