Stack Exchange
how do I refactor code that is calling multiple methods on the same object?
I have code like this:
 context = area.window.create_cairo_context

 context.set_source_rgb(0, 0, 0)
 context.set_line_width(0.5)
 context.arc(x + width - radius, y + radius, radius, -90 * degrees, 0 * degrees)
 context.arc(x + width - radius, y + height - radius, radius, 0 * degrees, 90 * degrees)
 context.arc(x + radius, y + height - radius, radius, 90 * degrees, 180 * degrees)
 context.arc(x + radius, y + radius, radius, 180 * degrees, 270 * degrees)
 context.close_path
 context.stroke_preserve
 context.set_source_rgb(0.7, 1.0, 1.0)
 context.fill

Notice that I'm calling methods on the same object over and over again. Is there someway that Ruby will let me change the current object (self) to context so I can just keep calling these methods with no explicit receiver until I change scope?
Or, to put it simply: There must be some way to not have to type context over and over again!

This brings back painful memorys of Delphis with statement. shudder. I think the potential for obfuscating your code by doing this would outweigh any advantages of avoiding a few key strokes.

Possibly related question: http://stackoverflow.com/questions/4341161/is-there-a-ruby-method-that-just-returns-the-value-of-a-block

Use instance_exec or instance_eval
area.window.create_cairo_context.instance_exec do
  set_source_rgb(0, 0, 0)
  set_line_width(0.5)
  arc(x + width - radius, y + radius, radius, -90 * degrees, 0 * degrees)
  arc(x + width - radius, y + height - radius, radius, 0 * degrees, 90 * degrees)
  arc(x + radius, y + height - radius, radius, 90 * degrees, 180 * degrees)
  arc(x + radius, y + radius, radius, 180 * degrees, 270 * degrees)
  close_path
  stroke_preserve
  set_source_rgb(0.7, 1.0, 1.0)
  fill
end

Just to note: you can omit the parentheses around the arguments. This makes it look more like a configuration setting than writing a code. Ruby on Rails people, which I am not one of, seem to heavily prefer this way.
area.window.create_cairo_context.instance_exec do
  set_source_rgb  0,   0,   0
  set_line_width  0.5
  arc           x+width-radius, y+radius,        radius, -90*degrees, 0*degrees
  arc           x+width-radius, y+height-radius, radius, 0*degrees,   90*degrees
  arc           x+radius,       y+height-radius, radius, 90*degrees,  180*degrees
  arc           x+radius,       y+radius,        radius, 180*degrees, 270*degrees
  close_path
  stroke_preserve
  set_source_rgb  0.7, 1.0, 1.0
  fill
end


That worked perfectly! I vaguely remembered instance_exec from the Ruby Metaprograming book (great book, by the way), but I didn't even think of using it like this!

@marcusM I was in pain doing a similar thing when I was trying to use ruby/gnome2. Just added a note.

Why don't you just implement method chaining?  Return yourself from each method call so that you can do something like:
context.set_source_rgb(0, 0, 0)
       .set_line_width(0.5)
       .arc(x + radius, y + radius, radius, 180 * degrees, 270 * degrees)
       .close_path.fill


-1. Probably these methods are all defined on some GUI toolkit, and in order to do what you suggest, you have to go through the API, and redefine a huge amount of methods, which is not practical. Also a cause of a bug, if you missed redefining some method. If these were your own methods, you can do from the beginning what you suggest.

@sawa You've made a big assumption which wasn't mentioned by the OP.

+1 to counter the -1 because, while it may not work for the OP's situation, it's a good idea when it's possible.
