A block is a chunk of code that you can pass to a method, so the method can run that code whenever it wants.
Block Syntax
In Ruby, you can define blocks in two ways:
- Using curly braces
{}
- Using
do...end
Using Curly Braces
You can define a block using curly braces {}
. This is best suited for single-line blocks. For example,
[1, 2, 3].each { |num| puts num * 2 }
Output
2 4 6
Using do…end
You can define blocks using do...end
. This is preferred for multiline blocks. For example,
[1, 2, 3].each do |num|
doubled = num * 2
puts doubled
end
Output
2 4 6
Block Parameters
Blocks can accept parameters placed inside vertical bars | |
. These act like variables inside the block. For example,
[10, 20, 30].each { |number| puts number + 5 }
Output
15 25 35
Here, number is the block parameter representing each element during iteration.
Using yield to Execute a Block
Methods can execute the block passed to them using the yield
keyword. For example,
def greet
puts "Hello!"
yield if block_given?
end
greet { puts "Have a great day!" }
Output
Hello! Have a great day!
The method calls yield
to run the block. The block_given?
check ensures a block is present in order to avoid errors.
Note: If you use yield
without a block, Ruby will give an error called LocalJumpError
. That's why we check with block_given?
before calling yield
.
You can also capture a block as a Proc
object by adding &block
in the method parameters, allowing you to call the block explicitly. For example,
def greet(name, &block)
puts "Hello, #{name}"
block.call if block
end
greet("Alice") { puts "Welcome!" }
Output
Hello, Alice Welcome!
BEGIN and END Blocks
Ruby lets you run some code before your program starts and after it finishes using BEGIN
and END
blocks.
BEGIN
runs right at the start of the program.END
runs just after the program finishes execution.
Example
BEGIN {
puts "Start of the program."
}
END {
puts "End of the program."
}
puts "This is the main program."
Output
Start of the program. This is the main program. End of the program.
Note: BEGIN
and END
blocks are rarely used and typically reserved for special purposes.
Common Methods Using Blocks
Ruby provides many built-in methods that take blocks for iteration, transformation, and filtering.
Method | Description | Example |
---|---|---|
.each |
Iterates over each element in a collection. | [1, 2, 3].each { |n| puts n } |
.map |
Transforms each element and returns a new array. | [1, 2, 3].map { |n| n * 2 } |
.select |
Returns elements for which the block returns true . |
[1, 2, 3, 4].select { |n| n.even? } |
.times |
Executes a block a specified number of times. | 3.times { puts "Hi" } |
More on Ruby Blocks
You can pass both arguments and a block to a method. For example,
def repeat(count)
count.times { yield if block_given? }
end
repeat(3) { puts "Hi!" }
Output
Hi! Hi! Hi!
A proc (short for procedure) lets you save a block of code into a variable and use it later. For example,
message = Proc.new { puts "Welcome to Ruby!" }
message.call
# Output: Welcome to Ruby!
Here, we stored a block in the message variable and ran it using .call
.
You can also pass a proc to methods:
def run_twice(block)
block.call
block.call
end
greeting = Proc.new { puts "Hello World!" }
run_twice(greeting)
Output
Hello World! Hello World!
Here, we passed the greeting
proc into the method run_twice
, which calls it two times.
A lambda is like a proc, but it's a bit stricter. It checks the number of arguments, and behaves differently with return
statements. For example,
goodbye = -> { puts "Hello World!" }
goodbye.call
# Output: Hello World!
Here, ->
is the shorthand syntax for lambda.