Sonntag, 29. Juni 2014

Do the Proc! ... a Ruby closure

First of all, a Proc (short for procedure) is technically nothing more than a block. And since a block is a Ruby way of implementing a closure, a Proc is a closure too. That means a anonymous function, which stores its environment on creation time and has access to those referenced variables, even when invoked outside.
The original code example using a simple block:
class Array
  def aggregate
    self.inject(0) { |result, number| result += yield(number) }
  end
end
and using it like:
numbers = [1, 2, 3]
numbers.aggregate { |number| number ** 2 }
=> 14
but if the very same object has to return the same result somewhere else too, the logic (block) has to be duplicated:
numbers.aggregate { |number| number ** 2 }
=> 14
Procs solve this issue, because Proc objects can be saved like:
squaring_proc = Proc.new { |number| number ** 2 }
=> #
The Array#aggregate has to be made ready for Procs by adding the new parameter and sending the Proc#call message:
class Array
  def aggregate block
    self.inject(0) { |result, number| result += block.call(number) }
  end
end
aggregating it the Proc way:
numbers = [1, 2, 3]
numbers.aggregate squaring_proc
=> 14
and this Proc object can be reused as many as ...
The domain of a Proc is:
  1. wherever a block is required
  2. the block logic has to be duplicated (reused)

Further articles of interest:

Supported by Ruby 2.1.1