March 31, 2016

Using ES6 style {a, b, c} hash construct in Ruby

ES6 ships with a very handy syntax sugar to build Object(aka Hash in Ruby).

var year = 2016;
var month = 3;
var day = 30;
var theDate = { year, month, day };

Can I use the syntax in ruby? calling something simple as HandyHash(:year, :month, :day)?

To get the variable values, the method #HandyHash must be aware of the context who calls him. This is not recommend in Ruby.
If you pass bindin to the method, the paramaters become (binding, :year, :month, :day)... Weird. Why I should call binding here.

Another approach to get the caller context binding is to pass a block defined in it. To get the hash keys, I decide to wrap an array in the block.

def HandyHash(&list_block)
  variables = yield.map(&:to_s)
  Hash[
    variables.map do |variable|
      [variable.to_sym, list_block.binding.local_variable_get(variable)]
    end
  ]
end

Suppose you have year, month, day = 2016, 3, 30. Then you can build the Hash with HandyHash{[:year, :month, :day]}.

I have wrapped the logic in to a gem called simple_hash (the Github repo is here).