HTransform

Build Status

HTransform provides a simple DSL to transform a supplied hash with an arbitrary structure to another hash with an even more arbitrary structure.

Note: HTransform does not simply modify the hash you have passed in. It actually creates a new hash from scratch. It only copies or does transformations on the fields you specify in the transform block, unless you use the passthrough_remaining option (see below)

Support

Should work for both 1.8 and 1.9 rubies.

Install

Standard gem install.

    gem install htransform

Put this in your Gemfile.

    gem "htransform"

or

    gem "htransform", :git =>
      "git://github.com/joshkrueger/htransform.git"

Basic Usage

All you have to do is create a new class and inherit from HTransform.

    class ExampleHTransform < HTransform
    end

Inside your new class you just use the hopefully not-convoluted DSL.

    class ExampleHTransform < HTransform
      transform do
        input :from => "foo", :to => :bar
      end
    end

Theres also shorthand for you lazy folks.

    input "foo" => :bar

But how do I do more than just re-name my keys?

Let's start simple. Lets take the following hash

    { "foo" => "party" }

and have HTransform change it to

    { :foo => "Party" }

Its pretty easy!

    input "foo" => :foo, :via => :capitalize

See! Nice and simple!

HTransform with a block!

    input "foo" => :foo, :via => lambda { |x| x.capitalize }

Actually Using HTransform

So we have our ExampleHTransform we created above (with our capitalize transform), saved somewhere. Lets say its in your "lib" folder. Anywhere it's loadable via require should be fine.

    require 'htransform'
    require 'example_htransform'

    contrived_input_hash = { "foo" => "bar" }

    output_hash = ExampleHTransform.convert(contrived_input_hash)

and now output_hash should look like

    { :foo => "Bar" }

Slightly Less Basic Usage

Want to combine multiple input keys? HTransform CAN DO THAT

    input_multiple ["foo", "bar"] => :foo_bar

By default HTransform will just join the multiple elements with a space. i.e. "foo" and "bar" become "foo bar". Need something more complicated?

    input_multiple ["foo", "bar"] => :foo_bar, :via => lambda { |x| x.map{ |v| v.capitalize }.join(" ") }

Here, "foo" and "bar" become "Foo Bar". Easy right?

Hrmm. What about nested hashes? No problem. Just define the nesting order in an array.

Lets start with nested inputs. Given the hash

    { "foo" => { "bar" => "sample text" } }

and a desired hash of

    {  "example" => "sample text" }

we would give HTransform the following operation

    input ["foo", "bar"] => "example"

If we want the opposite, all we do is reverse it.

    input "example" => ["foo", "bar"]

Nested to nested?

    input ["foo", "bar"] => ["baz", "qux"]

this turns

    { "foo" => { "bar" => "hello world" } }

into

    { "baz" => { "qux" => "hello world" } }

Want to combine multiple inputs when one or more are an array?

    input [ [ "foo", "bar" ], "baz" ] => "combined nested hash"

Want to simply pass some parts of your original hash through? Simply specify the keys you want passed through:

    passthrough :this_one, :that_one

Want to pass every part of your original hash that was not transformed through? HTransform CAN DO THAT TOO! Simply add the following at the end of your transform block:

    passthrough_remaining

Note: You MUST specify it only at the end of your transform block, as Tranny needs to know all the keys that were transformed before it!

Shorthand Limitations

Hey, the shorthand isn't perfect and theres really only a couple scenarios I can think of. If you have a key on your input hash of :via, you can't use the shorthand.

    input :via => :not_via

That won't work. Why? I'm lazy So just use the long format.

    input :from => :via, :to => :not_via, :via => :capitalize

However, :from or :to will work just fine in the shorthand. The longhand syntax only works if both the :from and :to symbols are passed in.

    input :from => "from"

That will work.