One of Ruby's defining features is a block. A block can either be surrounded by { } or do end.
# Use { } for single line commands
3.times { puts "Hello"}
# Use do end for multi line commands
3.times do
puts "Hello"
end
The key to understanding blocks is the yield keyword. We use the yield keyword in our method definition to defer to the block of code that was passed in.
Let's take a closer look by implementing our own version of the times method.
def my_times
yield
yield
yield
end
We can call this method with a block and it will execute the block three times.
my_times { puts "Hello" }
We can do better. Let's define a my_times method for all instances of Integer.
class Integer
def my_times
i = 0
while i < self
yield
i += 1
end
end
end
Now we can call our my_times method on an instance of Integer just like the original times method.
3.times { puts "Hello" }
3.my_times { puts "Hello" }
We can pass in arguments to a block as well. We might have seen this with the each method:
[1, 2, 3].each { |x| puts x }
We can write our own my_each method like the following:
class Array
def my_each
i = 0
while i < self.length
yield(self[i])
i += 1
end
self
end
end
[1, 2, 3].each { |x| puts x }
[1, 2, 3].my_each { |x| puts x }
Top comments (0)