##Ruby Blocks
The best way for you to understand blocks in Ruby is to look at the code:
numbers = [3,2,1]
numbers.each do |x|
puts "#{x}"
sleep(1)
enda block contains the code that sits between do and end in your ruby code
Blocks are temporary methods without names. (we could call them anonymous methods). Instead of naming the method, we treat it like an argument to another method.
Instead of naming the method however, we treat a block like an argument to another method
some_numbers = [1,2,3,4]
some_numbers.each do |number|
puts number * number
endBlocks allow you to pass a series of instructions to a method as a special argument
You are already super familiar with blocks as you've been using them with .each .map etc.
Let's break down .map.
First we'll start with an array:
students = ["aj", "melvin", "ashley"]Next we'll call .map on the students array and use the .upcase method on each item:
completed_homework = students.map do |student|
student.upcase
endThe end result will be:
completed_homework
#=> ["AJ", "MELVIN", "ASHLEY"]So, what happened here?
.mapreturns a new array- containing the modified contents of the previous array
- leaving the original array as-is
- The new array (that
.mapreturns) is a result of the block's instructions.maptakes a block- uses the block instruction to transform the array items
- returns the results as a new array
Ruby offers a handy way to shorten your code if you're using the same operation of each of your array elements.
Let's look at our previous example of transforming the student array to see how this would work:
upcased = students.map(&:upcase)We know that we are going to use the upcase method on each item in the array.
Using the &: syntax notifies the ruby interpreter that it should take the same action on each array item.
note: While this pattern is not necessary, you will find it heavily used in many Ruby Libraries
class challenge 1:
- create an array of at least 4 numbers
- write a block that prints the exponent of each item in your array
- multiply the individual to to it's own power
- 44 (4 * 4 * 4 * 4)
- simply print the new results to the screen (don't worry about returning new values)
Yield can be a confusing concept to initially understand. However, if you don't overthink it, you'll find that a magical concept that can be very useful.
Let's look at an example
def my_method
puts "reached the top"
yield
puts "reached the bottom"
end
my_method do
puts "reached yield"
endAs stated in this excellent blog on Ruby Blocks:
when the execution of my_method reaches the line with the call to yield, the code inside the block gets executed. Then, when the code inside the block finishes, the execution of my_method continues.
Procs are for storing your block in a named variable
countdown = Proc.new do |x|
puts "#{x}"
sleep(1)
end
# instantiate an object of the Proc class (called a proc object)You can then invoke a Proc in place of your block.
numbers.each(&countdown)- Turn your exponent block into a proc
- Produce a new array with the exponents of your original array
some_numbers.each do |num|
puts num ** num
endexponify = Proc.new{|x| x ** x }
exponents = some_numbers.map(&exponify)- Complete the remaining Ruby Monk Challenges
- Complete the 02_calculator challenge in the Learn Ruby Test Suite
- Read this article