Module: Hashformer

Defined in:
lib/hashformer.rb,
lib/hashformer/date.rb,
lib/hashformer/version.rb,
lib/hashformer/generate.rb

Overview

This module contains the Hashformer methods for transforming Ruby Hash objects from one form to another.

See README.md for examples.

Defined Under Namespace

Modules: Date, Generate

Constant Summary collapse

VERSION =
"0.3.1"
G =

Shortcut to Hashformer::Generate

Generate

Class Method Summary collapse

Class Method Details

.[](path_item = :__hashformer_not_given) ⇒ Object

Convenience method for calling HF::G.chain() to generate a path reference and/or method call chain. If the initial path_item is not given, then the method chain will start with the input hash. Chaining methods that have side effects or modify the underlying data is not recommended.

Example:

data = { in1: { in2: ['a', 'b', 'c', 'd'] } }
xform = { out1: HF[:in1][:in2][3], out2: HF[].count }
Hashformer.transform(data, xform) # Returns { out1: 'd', out2: 1 }


302
303
304
# File 'lib/hashformer/generate.rb', line 302

def self.[](path_item = :__hashformer_not_given)
  path_item == :__hashformer_not_given ? HF::G.chain : HF::G.chain[path_item]
end

.get_value(input_hash, key) ⇒ Object

Returns a value for the given key, method chain, or callable on the given input_hash. Hash keys will be processed with Hashformer.transform for supporting nested transformations.



62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/hashformer.rb', line 62

def self.get_value(input_hash, key)
  if Hashformer::Generate::Chain::ReceiverMethods === key
    # Had to special case chains to allow chaining .call
    key.__chain.call(input_hash)
  elsif Hashformer::Generate::Constant === key
    key.value
  elsif key.respond_to?(:call)
    key.call(input_hash)
  elsif key.is_a?(Hash)
    transform(input_hash, key)
  else
    input_hash[key]
  end
end

.transform(data, xform, validate = true) ⇒ Object

Transforms data according to the specification in xform. The transformation specification in xform is a Hash specifying an input key name (e.g. a String or Symbol), generator, or transforming lambda for each output key name. If validate is true, then ClassyHash::validate will be used to validate the input and output data formats against the :@__in_schema and :@__out_schema keys within xform, if specified.

Nested transformations can be specified by using a Hash as the transformation value, or by calling Hashformer.transform again inside of a lambda.

If a value in xform is a Proc, the Proc will be called with the input Hash, and the return value of the Proc used as the output value.

If a key in xform is a Proc, the Proc will be called with the exact original input value from xform (before calling a lambda, if applicable) and the input Hash, and the return value of the Proc used as the name of the output key.

Example (see the README for more examples):

Hashformer.transform({old_name: 'Name'}, {new_name: :old_name}) # Returns {new_name: 'Name'}
Hashformer.transform({orig: 5}, {opposite: lambda{|i| -i[:orig]}}) # Returns {opposite: -5}


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/hashformer.rb', line 40

def self.transform(data, xform, validate=true)
  raise 'Must transform a Hash' unless data.is_a?(Hash)
  raise 'Transformation must be a Hash' unless xform.is_a?(Hash)

  validate(data, xform[:__in_schema], 'input') if validate

  out = {}
  xform.each do |key, value|
    next if key == :__in_schema || key == :__out_schema

    key = key.call(value, data) if key.respond_to?(:call)
    out[key] = self.get_value(data, value)
  end

  validate(out, xform[:__out_schema], 'output') if validate

  out
end