Sunday, June 10, 2007

Passing multiple functions/closures

Code blocks are a very nice feature in Ruby that makes doing simple call backs a breeze. I have seen on the web a couple complaints about this feature though. Some have complained that you can’t pass multiple blocks to a single method at a time. While this is true you can pass multiple closure like constructs to a single method. So lets do some quick code.

Here’s the class that we’ll be using

class A
  
# This method will just take a simple block
  def test1
    yield if block_given?
  end
  
# This method is taking a block as a parameter
  def test2(&block)
    block.call
if block_given?
  end
  
# This method takes 2 closures
  def test3(func1, func2)
    func1.call
    func2.call
  end
end

And here’s the different ways of passing blocks/closures

# Here is the basic block
a = A.new
a.test1 { puts
'A' }
a.test2 { puts
'B' }
 
# Here's how to pass multiple functions using lambdas
function1 = lambda { puts
'C' }
function2 = lambda { puts
'C' }
a.test3(function1, function2)
 
# Here's another way using Procs (lambdas are usually recommended)
function3 = Proc.new { puts
'D' }
function4 = Proc.new { puts
'D' }
a.test3(function3, function4)
 
# And yet another way
def callback
  puts
'E'
end
 
# If you wanted to use a method from within a class you would do
# = classInstance.method(:methodName)
function5 = method(
:callback)
function6 = method(
:callback)
a.test3(function5, function6)

One thing you’ll want to consider is that if you want to use a return statement in any of these then you will only get the expected result from the last two scenarios above. If you place a return statement in the others they will return to the caller whereas the lambda and method ways will return only from the closure.

No comments: