1

I am struggling with Ruby do/end blocks. For instance, I have the following example:

::ApplicationController.class_eval do
  def close_sdb_connection
    puts "Closing sdb connection."       
  end
end

What this piece of code does? Why we need blocks? What would be the equivalent code without the do/end blocks?

Boris Stitnicky
  • 12,444
  • 5
  • 57
  • 74
pinker
  • 1,283
  • 2
  • 15
  • 32
  • What your questions is about: do/end blocks or `class_eval` function? – Thiago Lewin Nov 11 '13 at 14:16
  • Maybe both. I would like first to understand the generic purpose of do/end blocks and their equivalent in other languages. Are they anonymous blocks? – pinker Nov 11 '13 at 14:17
  • [This article](http://www.robertsosinski.com/2008/12/21/understanding-ruby-blocks-procs-and-lambdas/) might be helpful. – zwippie Nov 11 '13 at 14:21

2 Answers2

2

do and end are reserved words. They have no generic higher purpose (at least until Matz goes nuts like Larry Wall and says they do). In your sample code, the external do ... end means the code block – same as { ... }. The internal end serves as the right delimiter of the def ... end method definition.

In the context of class_eval, the code sample in the OP does exactly the same thing as:

class ::ApplicationController
  def close_sdb_connection
    puts "Closing sdb connection."
  end
end

However, block statements, such as Foo.class_eval do ... end significantly differ from non-block statements, such as class Foo; ... end, as the blocks are closures over local variables.

It is interesting to note, that not each do ... end indicates a block.

Community
  • 1
  • 1
Boris Stitnicky
  • 12,444
  • 5
  • 57
  • 74
  • And in the context of class_eval what does this block does? thanks! – pinker Nov 11 '13 at 14:19
  • google for [Ruby `yield` `block_given?`] for the inside story. do-end takes a block of code and passes a handle to it into a method. That method can then store the handle to evaluate it later, or evaluate it right now. The method can change conditions before and after calling that block. The method can also change how that block looks up its variables. That's what that `class_eval` is doing. – Phlip Nov 11 '13 at 14:55
  • thanks. If I have the following code: `tag 'children:first' do |tag| ... end` what is the role of 'children:first'? the first param of `tag`? – pinker Nov 11 '13 at 15:44
  • @pinker: 'children:first' is a string, that has no special meaning to Ruby as such. It is the duty of the `#tag` method programmer to describe the method arguments and their meanings in the method's documentation, if ze hasn't done so, complain. – Boris Stitnicky Nov 11 '13 at 16:18
2

In general, a do ... end or { ... } block is used to put code inside that is not to be evaluated in the same way as the rest of the code. In particular, a block is evaluated under a certain binding (i.e., a certain assignment of local variables and the self keyword) at a certain timing for a certain number of times, all of which is controlled by the method that the block is attached to.

In this particular case, the block is evaluated with a binding different from the outside. Particularly, the code inside would be evaluated as if it were inside the class body of the receiver ::ApplicationController.

sawa
  • 165,429
  • 45
  • 277
  • 381