Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Introduction
2.
Blocks
3.
Procs
3.1.
Creating Procs
3.2.
Proc.new
3.3.
The Arity of a Proc
3.4.
Proc Equality
4.
Lambdas
4.1.
Defining Lambda
4.2.
Behavior with Arguments
4.3.
Behavior with Return
4.4.
Lambda Literals
5.
Invoking Procs and Lambdas
6.
Summary of Procs and Lambdas
7.
Frequently Asked Questions
7.1.
What are procs in Ruby?
7.2.
What are lambdas in Ruby?
7.3.
What distinguishes procs and lambdas in particular?
7.4.
Why do we use blocks in Ruby?
7.5.
What are the critical features of the lambda function?
8.
Conclusion
Last Updated: Mar 27, 2024
Easy

 Procs and Lambdas in Ruby

Author Anju Jaiswal
0 upvote

Introduction

In Ruby Magic, we enjoy diving into the magic that underlies the objects we use daily to comprehend how they function. We'll examine blocks, procs, and lambdas in this blog.

Ruby blocks, procs and lambdas

Blocks, Procs, and Lambdas are the three primary functions used by Ruby. Code blocks can be passed to methods using blocks, and they can also be stored in variables using procs and lambdas.

Blocks

Little anonymous functions called "ruby blocks" can be provided in methods. They may have several parameters and are enclosed in a do/end statement (often when the block has many lines) or between brackets {} (if the block is a one-liner).

Example:

['x','y','z'].each do |n|
  puts "#{n}!"
end
['a','b','c'].each { |n| puts "#{n}!" } # the one-line equivalent.
You can also try this code with Online Ruby Compiler
Run Code

 

A block is supplied to the Array#each method in this example, which executes the block for each item in the array and outputs the results to the console.

Output:

x
y
z
a
b
c

In Ruby, blocks are essential in the following ways:

  • The block has a return value and can take arguments.
  • Block doesn't have a name of its own.
  • Code fragments comprise a block.
  • A block can be given to a method call or is always called together with a function.
  • The yield statement invokes a block within a method with a value.
  • From within the method to which they are provided, blocks can be called methods.

Procs

What if you want to pass your function two blocks? How may your block be saved as a variable?

Ruby added procs so that blocks could be passed. Code snippets, known as "proc objects," are tied to a group of local variables. Once bound, the code can continue to access those variables when invoked in other contexts.

Creating Procs

Associating a block with a method specified with an ampersand-prefixed block argument will create a Proc object. Nothing prevents a procedure of this kind from returning the Proc object for use elsewhere:

# This method creates a proc from a block
def makeproc(&p) # Convert associated block to a Proc and store in p
   p # Return the Proc object
end
You can also try this code with Online Ruby Compiler
Run Code

 

We can generate a Proc object for ourselves by defining a makeproc method similar to this:

adder = makeproc {|x,y| x+y }
You can also try this code with Online Ruby Compiler
Run Code

Adder is now a reference to a Proc object. When a proc object is made this way, it is a proc, not a lambda. Every Proc object has a call method that, when used, executes the program code found in the block from which it was generated. For instance:

Proc objects can be provided to methods, saved in data structures, and used in other ways like any other object, in addition to invoking.

Proc.new

The most obvious way to create a new instance of the Proc class is to use this standard new method, which is supported by most classes. Proc.new returns a Proc object that is a proc and requires no arguments (not a lambda). A proc representing the block is returned when Proc.new is called with an attached block.

A proc representing the block associated with the containing method is returned if Proc.new is called without a block from within a method that does have an associated block. An option for using an ampersand-prefixed block argument in a method specification is to use Proc.new in this manner. For instance, the following two approaches are equivalent:

def invoke(&b)         
   b.call                
end                    
def invoke
  Proc.new.call
end                  

The Arity of a Proc

The quantity of arguments that a proc or lambda expects is known as its arity. (The word is derived from unary, binary, ternary, etc. "are." 's the suffix.) The arity method of proc objects returns the number of arguments they anticipate. For instance:

lambda{||}.arity # => 0. There won't be any arguments
lambda{|x| x}.arity # => 1. Expected only one argument
lambda{|x,y| x+y}.arity # => 2. Two arguments expected
You can also try this code with Online Ruby Compiler
Run Code

Proc Equality

The Proc class defines a == method to check the equality of two Proc objects.

It's crucial to realize, however, that two procs or lambdas are not identical just because they have the same source code:

puts lambda {|y| y*y } == lambda {|y| y*y } # => false
You can also try this code with Online Ruby Compiler
Run Code

Output:

false

The == method only returns true if one Proc is a clone or duplicate of the other:

p = lambda {|y| y*y }
q = p.dup
puts p == q # => false: the two procs are equal
puts p.object_id == q.object_id # => false: they are not the same object
You can also try this code with Online Ruby Compiler
Run Code

Output:

false
false

Lambdas

With Ruby, the lambda keyword is used to create a lambda function. It requires a block and can set zero or more parameters.

Defining Lambda

A lambda is a particular syntax used to define a block and its parameters.

This lambda can be stored in a variable for later usage.

The following is the syntax for defining a Ruby lambda:

Lambda_example = -> { puts "This is a lambda" }
Lambda_example.call
You can also try this code with Online Ruby Compiler
Run Code

Output:

This is a lambda

Behavior with Arguments

Unlike Proc Functions, Lambda Functions are highly particular about the arguments they accept:

adds_four = -> v { v + 4 }
adds_four.call(4, 5, 6)
# ArgumentError: Incorrect argument count (given: 3, expected: 1)
You can also try this code with Online Ruby Compiler
Run Code

Output:

main.rb:2:in `block in <main>': wrong number of arguments (given 3, expected 1) (ArgumentError)
    from main.rb:3:in `<main>'

In this, they behave much more like methods and may result in fewer perplexing errors.

Behavior with Return

Instead of attempting to return from the method's outside context, lambda functions will treat the return as a local return, this shows the difference between procs and lambdas:

def some_method(a, b)
  adds_three_unless_gt_three = -> v {
    return v if v > 3
    v + 3
  }

  puts adds_three_unless_gt_three.call(a) +
  adds_three_unless_gt_three.call(b)
end

some_method(1,1) #=>8
some_method(5,5) #=>10
You can also try this code with Online Ruby Compiler
Run Code

Output:

8
10

Lambda Literals

For defining lambdas as literals, Ruby 1.9 enables a completely new syntax. We'll start with a Ruby 1.8 lambda that was developed using the lambda method:

suc = lambda {|y| y+1}
You can also try this code with Online Ruby Compiler
Run Code

We can change this to a literal in Ruby 1.9 by doing the following:

  • Place the comma -> in place of the method name lambda.
  • Place the argument list just before and outside of the curly braces.
  • The parameter list delimiters should be changed from || to ().

With these adjustments, we obtain a lambda literal for Ruby 1.9:

suc = ->(y){ y+1 }
You can also try this code with Online Ruby Compiler
Run Code

Invoking Procs and Lambdas

Procs and lambdas cannot be invoked in the same manner that methods may since they are objects and not methods. You cannot call p as a method if it refers to a Proc object. However, since p is an object, you can call one of p's methods. The Proc class defines a method called call. The code in the original block is executed when this method is used. The arguments you send to the call method become the arguments for the block, and the block's return value becomes the call method's return value:

f = Proc.new {|x,y| 1.0/(1.0/x + 1.0/y) }
z = f.call(2,4)
You can also try this code with Online Ruby Compiler
Run Code

Output:

1.3333333

The Proc class also defines the array access operator to function similarly to the call. This indicates that you can call a proc or lambda using a syntax similar to a method invocation, except that square brackets are used in place of parentheses. For instance, the code below might be used in place of the proc invocation above:

z = f[x,y]
You can also try this code with Online Ruby Compiler
Run Code

Ruby 1.9 adds a second way to call a Proc object; instead of using square brackets, you can use parentheses that have a period in front of them:

z = f.(x,y)
You can also try this code with Online Ruby Compiler
Run Code

.() appears to be a method call without the method name. This is syntactic sugar that calls the call method rather than an operator that can be defined. It is not restricted to Proc objects and can be used with any object that defines a call method.

Summary of Procs and Lambdas

We've now thoroughly explored blocks, procs and lambdas; let's zoom out and summarize the comparison.

  • In Ruby, blocks are frequently used to pass pieces of code to functions. A block can be implicitly passed without being converted into a proc using the yield keyword.
  • When sending a block to a method with ampersand-prefixed parameters, the method's context creates a proc. Procedures operate like blocks despite being able to be stored in a variable.
  • By enforcing arity and returning as methods rather than in their parent scope, lambdas are procs that behave like methods.
    Check out this problem - Find Duplicate In Array

Frequently Asked Questions

What are procs in Ruby?

A Proc object is a container for a block of code that can be called, handed to another Proc or method, and saved in a local variable. The foundation of Ruby's functional programming features is the concept of Proc.

What are lambdas in Ruby?

In Ruby, a lambda is an object similar to a proc. Unlike a proc, a lambda requires a specific number of arguments passed to it, returning to its calling method rather than returning immediately.

What distinguishes procs and lambdas in particular?

The primary variations. A lambda, as opposed to a proc, first verifies the number of arguments supplied to it.

Why do we use blocks in Ruby?

You have utilized blocks if you have previously used each. Because it enables you to store and reuse a small portion of logic (code), Ruby blocks are helpful. This might entail sending information to a file, determining whether two elements are equal, or even producing an error message.

What are the critical features of the lambda function?

Syntactically, lambda functions can only return a single expression. They can be utilized inside of other functions as an anonymous function. Because lambda functions always return a single expression, they do not require a return statement.

Conclusion

In this post, you learned how to create and work with blocks, procs and lambdas in ruby through various examples.

Here are a few key websites that will aid in your exploration of Ruby's Procs and Lambdas.

 

Refer to our Guided Path on Coding Ninjas Studio to upskill yourself in Data Structures and AlgorithmsCompetitive ProgrammingJavaScriptSystem DesignMachine learning, and many more! If you want to test your competency in coding, you may check out the mock test series and participate in the contests hosted on Coding Ninjas Studio! But if you have just started your learning process and are looking for questions asked by tech giants like Amazon, Microsoft, Uber, etc; you must look at the problemsinterview experiences, and interview bundle for placement preparations.

Nevertheless, you may consider our paid courses to give your career an edge over others!

Do upvote our blogs if you find them helpful and engaging!

Happy Learning!!

Thankyou from coding ninjas
Live masterclass