Blocks are very handy and syntactically simple, however we may want to have many different blocks at our disposal and use them multiple times. As such, passing the same block again and again would require us to repeat ourself. However, as Ruby is fully object-oriented, this can be handled quite cleanly by saving reusable code as an object itself. This reusable code is called a Proc (short for procedure). The only difference between blocks and Procs is that a block is a Proc that cannot be saved, and as such, is a one time use solution.

Procs in Ruby are first-class objects, since they can be created during runtime, stored in data structures, passed as arguments to other functions and returned as the value of other functions.

When you pass a block to a method such as &block below: 

def variable(&block)
	puts 'Here goes:'
	case block.arity
		when 0
			yield
		when 1
			yield 'one'
		when 2
			yield 'one', 'two'
		when 3
			yield 'one', 'two', 'three'
	end
	puts 'Done!'
end

What is actually happening is the block is being converted to a Proc object (using .to_proc) which can be passed as a parameter.

This conversion of a block to a Proc for passing a block to a method using &block is expensive and inefficient.  It is better to use yield within the method or use Proc.new.call when block_given?.  See example below:

def sometimes_proc_new(flag)
  if flag && block_given?
    Proc.new.call
  end
end

Conditionals such as if block_given? ensures that the Proc is only created when you actually need it (aka lazy loading). 

I’ve been diving into the JavaScript world recently.  Today I realized that JS functions are not like instance methods in Ruby.  They are actually more like Ruby Proc objects that you can pass to methods and other blocks.  

Procs like functions are bound to a set of local variables (aka Closures).

On first look, lambdas seem to be exactly the same as Procs. However, there are two subtle differences. The first difference is that, unlike Procs, lambdas check the number of arguments passed.  

The second difference is that lambdas have diminutive returns. What this means is that while a Proc return will stop a method and return the value provided, lambdas will return their value to the method and let the method continue on. Confused? Lets take a look at an example.

def proc_return
  Proc.new { return "Proc.new"}.call
  return "proc_return method finished"
end

def lambda_return
  lambda { return "lambda" }.call
  return "lambda_return method finished"
end

puts proc_return
puts lambda_return

# => Proc.new
# => lambda_return method finished

Here is an old blog on Block & Procs in Ruby.  The examples helped me understand the concept better.  Here is another article which has benchmarked performance differences between yield, &block, and lazy loading conditionals.