Yahm

Yahm is a hash to hash translator for ruby.

Installation

Add this line to your application's Gemfile:

gem 'yahm'

And then execute:

$ bundle

Or install it yourself as:

$ gem install yahm

Dependencies

None

Usage

Most basic example

require "yahm"

class Record
  extend Yahm::HashMapper

  define_mapper :from_other_record do
    map "/record/id", to: "/id"
  end
end

Record.new.from_other_record({ ... })
=> { :id => "..." }

More advanced examples

require "yahm"

class Record
  extend Yahm::HashMapper
  attr_accessor :translated_hash

  define_mapper :from_other_record, call_setter: :translated_hash= do
    map "/record/id",         to: "/id"
    map "/record/count",      to: "/count", processed_by: :to_i
    map "/record/subject[0]", to: "/subjects/most_important_subject"
    map "/record/languages",  to: "/languages", force_array: true
    map "/record/authors",    to: "/authors", split_by: ";"
    map "/record/version",    to: "/version", default: 1
  end
end

Record.new.from_other_record({ ... })
=> { :id => "...", :count => ..., :subjects => { :most_important_subject => "..."}, ... }

Record.translated_hash
=> { :id => "...", :count => ..., :subjects => { :most_important_subject => "..."}, ... }

Examples for using to

The to option of a mapping rule can either be a string, naming the path in the resultung hash or a proc, which is executed in the context of the created mapper. The result hash can be accessed by @result.

require "yahm"

class Record
  extend Yahm::HashMapper

  define_mapper :from_other_record do
    def funky_method(value)
      @result[:is_funky] = true if funky?(value)
    end

    map "/record/count",        to: "count"
    map "/record/name",         to: lambda { |v| funky_method(v) }
  end
end

Examples for using processed_by

You can pass symbols, lambdas or procs as processed_by option. Inside of lambdas or procs, self corresponds to the context of the defined mapper. To access the context of to extended object, use _self.

require "yahm"

class Record
  extend Yahm::HashMapper

  def process_bool_string(string)
    string == "true" ? true : (string == "false" ? false : nil)
  end

  define_mapper :from_other_record do
    def cheap?(price)
      price.to_i < 20
    end

    map "/record/id",           to: "id",        processed_by: :to_i
    map "/record/count",        to: "count",     processed_by: proc { |v| v.to_i }
    map "/record/subject",      to: "subjects",  processed_by: :downcase
    map "/record/price",        to: "is_cheap",  processed_by: lambda { |v| cheap?(v) }
    map "/record/is_available", to: "available", processed_by: lambda { |v| _self.process_bool_string(v) }
  end
end

Private mappers

You can control, wether a mapper is defined as a private method or not by passing the private:[true|false] option to define_mapper.


class Record
  extend Yahm::HashMapper

  define_mapper :my_private_mapper, private: true do
    map "/some/internals", to: "internals"
  end
end

Contributing

  1. Fork it ( http://github.com/ubpb/yahm/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request