method method parameter marks the start of the block
Multi- object block parameter
line 1.upto(4) do |number|
Block: puts “Echo! #{number}” any Ruby code we want
inside the block
end marks the end of the block
Single-
line
1.upto(4) { |number| puts “Echo! #{number}” }
Block: marks the start of the block marks the end of the block
Online Mastering Ruby Blocks & Iterators Course http://pragmaticstudio.com/ruby-blocks Copyright © The Pragmatic Studio
name = “Curly” variables outside the block can be shared inside the block
Scoping number = 99
Rules temp = 32.0 block parameters are always local to the block
3.times do | number ; temp | block-level variables are reserved for inside the block
! name = “Moe”
! age = 25 variables defined inside a block are local to the block
temp = 98.6
0: Moe is 25 (98.6)!
puts “#{number}: #{name} is #{age} (#{temp})”
1: Moe is 25 (98.6)!
end
2: Moe is 25 (98.6)!
puts age Error
puts name Moe
puts number 99
puts temp 32.0
Online Mastering Ruby Blocks & Iterators Course http://pragmaticstudio.com/ruby-blocks Copyright © The Pragmatic Studio
each moe@example.com larry@example.com curly@example.com
Iterator orders =[ $10.00 , $20.00 , $30.00 ]
curly@example.com
}
$30.00 one-by-one each
larry@example.com element in the array is
$20.00 assigned to the block
acts like a loop moe@example.com parameter
$10.00
orders.each do |order|
puts order.email
end
Online Mastering Ruby Blocks & Iterators Course http://pragmaticstudio.com/ruby-blocks Copyright © The Pragmatic Studio
scores = [ 85, 105, 71, 113, 122, 94]
synonym: find_all
high_scores = scores.select { |score| score > 100 }
select returns an array containing all
high_scores == [ 105, 113, 122 ] elements for which the block is true
low_scores = scores.reject { |score| score > 100 }
reject returns an array containing all
low_scores == [ 85, 71, 94 ] elements for which the block is false
Online Mastering Ruby Blocks & Iterators Course http://pragmaticstudio.com/ruby-blocks Copyright © The Pragmatic Studio
scores = [ 85, 105, 71, 113, 122, 94]
high_scores = scores.any? { |score| score > 100 }
any? If the block returns a true value,
high_scores == true then the method returns true.
first_high_scores = scores.detect { |score| score > 100 }
detect Returns the first element in the
first_high_scores == 105 collection that matches the
criteria in the block.
Online Mastering Ruby Blocks & Iterators Course http://pragmaticstudio.com/ruby-blocks Copyright © The Pragmatic Studio
scores = [ 85, 105, 71, 113, 122, 94]
name of name of
first array second array
partition high, low = scores.partition { |score| score > 100 }
an array containing all an array containing all
elements for which the elements for which the
block is true block is false
high == [ 105, 113, 122 ] low == [ 85, 71, 94 ]
Online Mastering Ruby Blocks & Iterators Course http://pragmaticstudio.com/ruby-blocks Copyright © The Pragmatic Studio
scores = [ 85, 105, 71, 113, 122, 94]
synonym: collect using map! will modify the original array
doubled = scores.map { |score| score * 2}
map returns an array the
doubled == [ 170, 210, 142, 226, 244, 188] same size as the
original array
synonym: inject initial value of sum
reduce total = scores.reduce(0) { |sum, score| sum + score }
total == 590 the accumulator value
Online Mastering Ruby Blocks & Iterators Course http://pragmaticstudio.com/ruby-blocks Copyright © The Pragmatic Studio
yields control to the associated block
yielding def roll
variable that number = rand(1..6) parentheses are optional
captures the value
of yield returned
result = yield(“Larry”, number) arguments to yield are
passed directly to the
from the block associated block as
block parameters
roll do |name, number|
the value of the
last expression in puts “#{name} rolled a #{number}!”
the block is
automatically
number * 10
passed back to end
the method as
the value of yield
puts “The block returned #{result}.”
end
Online Mastering Ruby Blocks & Iterators Course http://pragmaticstudio.com/ruby-blocks Copyright © The Pragmatic Studio
class MovieQueue
custom
include Enumerable
iterators
! def initialize(name)
Defining an each method and @name = name
including Enumerable allows you to !
call all the Enumerable methods ! @movies = [] Defining an each method that
outside the class. For example: ! end iterates through all the elements
queue.select { |m| m.duration > 140 } def add_movie(movie) in the array allows you to call each
@movies << movie outside the class, like so:
queue.each { |movie| movie.title }
end
! def each
! @movies.each { |movie| yield movie}
! end
each method on Array class
end
Online Mastering Ruby Blocks & Iterators Course http://pragmaticstudio.com/ruby-blocks Copyright © The Pragmatic Studio
Execute This pattern is used when you want to execute around some code like a toggle switch:
Around turn something on, yield to a block to do something, and then remember to turn it off.
def in_airplane_mode
@airplane_mode = true
yield
rescue Exception => e
captures any exception and prints it out
puts e.message
ensure guarantees that any code in this clause
@airplane_mode = false is always run regardless of whether an
end exception is raised
Online Mastering Ruby Blocks & Iterators Course http://pragmaticstudio.com/ruby-blocks Copyright © The Pragmatic Studio
This pattern, sometimes referred to as Self Yield or Block Initialization, makes it clear that all
Self the code in the block is focused on initializing the object.
Yield class Canvas
attr_accessor :width, :height, :color
!
initial object: def initialize
width =100 @width = 100
height = 100 @height = 100
color = :green @color = :green yields the current object to the block
yield self if block_given? for further initialization, but only if a
end block is given
end references the current object being created
final object created: !
width = 800 canvas = Canvas.new do |c|
height = 600 c.width = 800
color = :green c.height = 600
end
Online Mastering Ruby Blocks & Iterators Course http://pragmaticstudio.com/ruby-blocks Copyright © The Pragmatic Studio
This pattern is commonly used when dealing with expensive and/or limited resources such
Managing as network connections, files, and such. It ensures they’re opened and closed consistently.
Resources def self.open(user, password) def self.open(user, password)
gateway = self.new(user, password) resource = self.new(user, password)
gateway.connect open resource resource.open
!
return gateway unless block_given? return resource unless block_given?
! !
begin begin
yield(gateway) yield resource yield(resource)
ensure ensure
gateway.disconnect ensure resource resource.close
end is closed end
end end
! !
Gateway.open(“admin”, “secret”) do |g| Resource.open(“admin”, “secret”) do |r|
# use gateway referenced in ‘g’ # use the resource referenced in ‘r’
end end
Online Mastering Ruby Blocks & Iterators Course http://pragmaticstudio.com/ruby-blocks Copyright © The Pragmatic Studio