class PayloadAdapter < Dry::Transformer::Pipe
import Dry::Transformer::HashTransformations
import Dry::Transformer::Recursion
import Dry::Transformer::Conditional
define! do
recursion(is(::Hash, map_keys(->(key) { Hanami.app["inflector"].underscore(key) })))
end
end
This is happening because all the examples are built around using Dry::Transformer directly, whereas any bare words in the define! block are generating ASTs, not objects.
This is easily the most confusing thing about this library.
Here’s how you would write this as-is:
class PayloadAdapter < Dry::Transformer::Pipe
import Dry::Transformer::HashTransformations
import Dry::Transformer::Recursion
import Dry::Transformer::Conditional
define! do
recursion t(:is, Hash, t(:map_keys, ->(key) { Hanami.app["inflector"].underscore(key) }))
end
end
However, I don’t think the next person who comes along is going to understand what they’re looking at.
Here’s an approach to this that I have taken
module Transform
class Registry
extend Dry::Transformer::Registry
import Dry::Transformer::ArrayTransformations
import Dry::Transformer::HashTransformations
import Dry::Transformer::Conditional
class << self
def deep_transform_keys(hash, fn)
hash.each_with_object({}) do |(key, value), result|
result[fn.(key)] = if value.is_a?(Hash)
deep_transform_keys(value, fn)
elsif value.is_a?(Array)
value.map { deep_transform_keys(_1, fn) }
else
value
end
end
end
end
end
class Function < Dry::Transformer::Pipe
extend Dry::Initializer
end
end
class PayloadAdapter < Transform::Function
option :inflector, default: -> { Hanami.app.inflector }
import :deep_transform_keys, from: Transform::Registry
define! do
deep_transform_keys(&:underscore)
end
def underscore(key) = inflector.underscore(_1.to_s)
end
def deep_transform_keys(value, fn)
if value.is_a?(Hash)
value.each_with_object({}) do |(key, value), result|
result[fn.call(key)] = deep_transform_keys(value, fn)
end
elsif value.is_a?(Array)
value.map { deep_transform_keys(_1, fn) }
else
value
end
end
If you are using this in any code base, maybe this message will save you from a bugfix in the future.