Hello there, today we are going to learn about concepts of closures in Ruby. In Ruby, Closure can be viewed as a variable that can be assigned to another variable or passed as an argument to any function.
A closure block can be defined in one scope and then called in another. Closure always remembers the variables inside its scope at the time of creation, and when called, it can access the variables even if they are not in the current scope, implying that closure retains its knowledge of its lexical context at the time of definition.
Closures in Ruby are Blocks, Procs, and Lambdas So, let’s get going with explaining each closure one by one.
Blocks
Blocks are the most basic type of Closures in Ruby. It is not an object but rather a snippet of code contained between braces {} or do...end.
We can send one or more variables into our block depending on how the code block is constructed.
We can use the yield statement to invoke a method block with a value.
It does not have a name of its own.
Syntax:
Using {} block_name { #statements_to_be_executed }
Using do…end block_name do #statement-1 #statement-2 … … end
Example
# Ruby program for blocks
def print_one_time
puts"I am Method"
yield
end
# Block 1
print_one_time { puts "Hello! I am Block 1" }
def print_two_times
yield
yield
end
# Block 2
print_two_times { puts "Hello! I am Block 2" }
Output
I am Method
Hello! I am Block 1
Hello! I am Block 2
Hello! I am Block 2
Explanation
The method name in the preceding example is printed one time. The method statement is first invoked, which displays "I am Method." However, as soon as the yield statements execute, the control is passed to the block, which executes its statements and prints "I am Method." When the block is executed, control is returned to the method, and the method continues to execute from where the yield statement was called. As illustrated in the print two times function, we can also use multiple yield statements in a single method.
Procs
The second form of Closures in Ruby is Procs, which is similar to block but has a few peculiarities, such as being assigned or stored in a variable and being executed by executing the Call function. A method can be passed one or more procs. As we all know, a block is not an object, but a procedure is. It is a block that has been converted into an object of the Proc class, which is why the Proc resembles a class instantiation.
Syntax:
varName = Proc.new {# Statement}
# Executing Procs
varName.call
Example 1
# Ruby program for Procs
# Creating proc
proc_1 = Proc.new{"CodingNinjas"}
# Executing proc
# Using .call method
puts proc_1.call
Output
CodingNinjas
Explanation
In the preceding example, we assign a block to an instance of the Proc class, assign it to the variable example, and then call the method. Make a call on it.
x = 4, y = 5
x = 7, y = 10
x = 31, y = 40
x = 91, y =
Explanation
In this example, we use the .call method to give the input to Proc. Procs are more accepting of arguments. If the proc has several arguments, it fills missing arguments with nil and deconstructs a single array parameter. Extra arguments do not result in an error.
Lambda
Lambda and Procs are similar in that there isn't much difference between them. A lambda can also be defined as a particular syntax for defining a block and its parameters. Lambda is similar to regular methods in that they enforce the number of parameters supplied when they are called and also return like regular methods (It treats return keyword just like methods). We will get an ArgumentError if we give a parameter to a lambda that does not anticipate it.
Syntax:
varName = -> {# Statement}
Example
# Ruby program for lambda
# Creating lambda
multiply = ->(y){ y * 2 }
# Displaying result
puts multiply.call(10)
# Creating lambda
name = lambda{"CodingNijas"}
# Displaying result
puts name.call
Output
20
CodingNijas
Explanation
In this example, we are using the call method to display the results produced by variables multiplied and name. In multiply, we are passing values of y=10 in call function, and in name, we have a predefined lambda expression as “CodingNinjas”.
Frequently Asked Questions
What distinguishes procs and blocks from one another?
A proc is an instance of the Proc class (observe the lowercase p). This enables us to assign it to variables and call methods on it. Procs may also self-return. A block, on the other hand, is merely a component of the syntax of a method call.
How to use Ruby methods?
We must first define a Ruby method before we can utilize it. The keywords def and end are used to define it. The name of the Method always begins with a lowercase letter.
What is the primary difference between a module and a class?
A module cannot be instantiated or subclassed, whereas a class cannot implement mixins.
How are blocks written in Ruby?
Curly braces or a do-end statement enclose blocks. Do-end is typically used for blocks that cross multiple lines, whereas for blocks that only cross one line. Arguments for blocks should be defined between two pipe | Characters.
What in Ruby is a closure?
In computer science, a closure is a piece of code that carries the context of its creation with it at all times. Closures in Ruby are sections of code or methods with variables connected to the scope environment.
Conclusion
In this article, we have discussed the concept of Closures in Ruby. We started with the introduction of Closures in Ruby, and various types of Closures in Ruby, and concluded with examples of Closures in Ruby.