I’m definitely a lambda-guy. I’m addicted to simplicity, beauty and intelligibility of closures. He who claims there is syntax clearer than arr.each { |e| … }, let him throw the first stone at me. After all yielding is much more of human nature than jumping.

However there are two cases when yield seems to be hardly used. First is the &-shorthand to method within another codeblock:

def uglify items
  raise ArgumentException.new unless items.respond_to? :each
  items.each { |e| yield e }
end

If we try to shorten the |e| yield e clause with &-notation we’ll gain no success, since yield is a keyword rather than method of a very superclass (like Object or Kernel.) But who cares?

Well, I do. Because there is a second, much more vital situation when yield sucks. It is re-passing a codeblock to a subsequent method:

def cleanup
  # do some cleanup if block_given?
end

def evaluate_lua
  cleanup yield if block_given?
  # do actual evaluate
end

The latter will throw an odd error ArgumentError: wrong number of arguments (1 for 0). The cleanup &yield neither works, if one were curious.

What’s the problem to use explicit &cb param here? There are two as usual. First is an aesthetics, which matters a lot in Ruby. The last and not the least is that instantiating a new Proc object leads to a surprisingly heavy performance penalty (≈ five times slower.) Happily, there is a not wide-known feature of Proc.new constructor. Being called without a block within a method with an attached block, it converts that block to the Proc object. It means that both

def uglify items
  raise ArgumentException.new unless items.respond_to? :each
  items.each(&Proc.new)
end

and

def cleanup
  if block_given?
    # do some cleanup if block_given?
  end
end

def evaluate_lua
  cleanup &Proc.new
  # do actual evaluate
end

will work as expected without extra performance penalty.