Working with lambda functions in Ruby

Ruby provides an easy way of working with closures: the code blocks. Everybody that uses Ruby for a minimum amount of time knows how code blocks work. You can do it this way:

def foo(a)
  # Some code here, create n
  # More code here

# Some code here, create x
foo(x) do |y|
  # Your code block goes here. You can access any variable from previous scope
  # But everything created here is exclusive for this scope

Or like this:

foo(x) { |y| do_stuff_here }

This is a lot similar, but not exactly equal, to what you can do with a functional language (where you can, for example, pass a function as an argument to another). Code blocks are really practical, but they have some limitations:

  1. You can only pass one block per function;
  2. Blocks can’t return anything. If you need the result of an anonymous function, blocks are not what you need. That’s because the return is non-local; that is, the function that is declaring the block will be the one returning.
  3. You can’t pass the same block more than once, because you can’t storing it anywhere.

But there are two other ways of creating anonymous functions in Ruby that addresses some or all of these problems: procs and lambdas.

1. Procs

Actually, I lied. You can store blocks somewhere. And the place is a proc.

Blocks are, actually, a way for creating procs. They are the same type of closure: they have access to the scope that creates them, their return is non-local and they can be passed as a parameter to another function. If you try to call a proc with additional parameters, they will be ignored, just like it would happen on blocks.

Generally, it is better to use a block than a proc, except when you need to pass more than one to a function or when you want to send the same block to two functions.

But how do you use a Proc?

Simple enough:

def receiver_method(parameter)
  y = 5

test_proc = { |x| x * 3 }
puts receiver_method(test_proc)

This will print 15 on the screen.

2. Lambdas

Lambdas are similar to procs, but there are two main differences:

  1.  If you try to pass the wrong number of parameters to a lambda function, it’ll throw an error
  2. Lambdas can return values without affecting the callee

That is, you can create a lambda function like this:

fat = lambda do |x|
  result = 1
  1.upto x do |i|
    result *= i
  return result

And call it wherever you want that it’ll not affect the flow of the code. In this aspect, lambda functions are similar to regular functions.

Beginning in Ruby 1.9, there is a cleaner syntax for creating lambda functions:

square = ->(x) { x * x }

And actually, lambdas are ALSO procs internally. But this doesn’t matter a lot from a pragmatic point of view.

So, that’s it. Whoever likes functional languages, Ruby has the tools for the job.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s