Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

#with(object) &block trick

Tags:

idioms

ruby

There is a common idiom of using substitutions like:

def with clazz, &block
  yield clazz
  clazz
end

with Hash.new |hash|
  hash.merge!{:a => 1}
end

Is there a way to go further and define #with to have a possibility of doing:

with Hash.new |hash|
  merge!{:a => 1} 
end

or even:

with Hash.new do
  merge!{:a => 1}
end

?


UPDATE

Later accidentally I found exactly what I was looking for (solution similar to the accepted one): http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/19153

UPDATE 2

It was added to sugar-high/dsl in https://github.com/kristianmandrup/sugar-high

UPDATE 3

docille project on Github exploits this idea very nicely.

like image 920
Stanislav Pankevich Avatar asked Aug 19 '11 01:08

Stanislav Pankevich


1 Answers

If you are referring to the way in which Rails does routing then I think you need to do something like this

def with(instance, &block)
  instance.instance_eval(&block)
  instance
end

with(Hash.new) do
  merge!({:a => 1})
  merge!({:b => 1})
end

This is how I can see it being done in the Rails source anyway start by looking at the draw method in action_pack/lib/action_dispatch/routing/route_set

like image 64
Paul.s Avatar answered Sep 19 '22 23:09

Paul.s