Skip to content

Instantly share code, notes, and snippets.

@MrAlexLau
Created March 6, 2016 23:20
Show Gist options
  • Save MrAlexLau/703aedad2dd62825fa5b to your computer and use it in GitHub Desktop.
Save MrAlexLau/703aedad2dd62825fa5b to your computer and use it in GitHub Desktop.
Exploring Procs, blocks, and lambda expressions
# these notes walk 2 excellent blogs posts:
# 1. http://awaxman11.github.io/blog/2013/08/05/what-is-the-difference-between-a-block/
# 2. http://mixandgo.com/blog/mastering-ruby-blocks-in-less-than-5-minutes
arr = [1, 2, 3]
########################################################
# example of a block
puts "block syntax demo"
arr.each do |element|
puts element # everything at this level of code is a block
end
########################################################
########################################################
# example of a Proc
puts
puts "proc syntax demo"
proc = Proc.new { |element| puts element }
arr.each(&proc)
proc = Proc.new { |an_arg| puts "you passed '#{an_arg}' to this proc" }
proc.call(1)
########################################################
########################################################
# example of a lambda expression
puts
puts "lambda syntax demo"
lambda_expression = lambda { |element| puts element }
arr.each(&lambda_expression)
lam = lambda { |an_arg| puts "you passed '#{an_arg}' to this lambda expression" }
lam.call(2)
########################################################
########################################################
puts
puts "inspecting the class of Procs and lambda expressions"
puts "proc instance has a class of: #{proc.class}"
puts "lambda instance has a class of: #{lambda_expression.class}" # yes, this still returns Proc
########################################################
########################################################
# test the scope of the 'return' keyword in a Proc
puts
def proc_return_test
puts "beginning of proc_return_test"
proc_that_returns = Proc.new { return }
proc_that_returns.call
puts "end of proc_return_test"
end
# call this method to see how it behaves
# spoiler alert: only the first `puts` statement is called
# the lesson here is that the `return` within the Proc *does* affect when proc_return_test returns
proc_return_test
########################################################
########################################################
# test the scope of the 'return' keyword in a lambda expression
puts
def lambda_return_test
puts "beginning of lambda_return_test"
lambda_that_returns = lambda { return }
lambda_that_returns.call
puts "end of lambda_return_test"
end
# call this method to see how it behaves
# spoiler alert: both the first and second `puts` statements are called
# the lesson here is that the `return` within the lambda does not make lambda_return_test return
lambda_return_test
########################################################
########################################################
# try calling a Proc with different numbers of arguments
puts
proc = Proc.new { |an_arg| puts "you passed '#{an_arg}' to this Proc" }
proc.call("tacos")
proc.call
begin
proc.call("tacos", "burritos", "guacamole")
rescue ArgumentError => e
puts "An exception was raised with the message: #{e.message}"
end
########################################################
########################################################
# try calling a lambda expression with different numbers of arguments
puts
lam = lambda { |an_arg| puts "you passed '#{an_arg}' to this lambda expression" }
lam.call("tacos")
begin
lam.call
rescue ArgumentError => e
puts "An exception was raised with the message: #{e.message}"
end
begin
lam.call("tacos", "burritos", "guacamole")
rescue ArgumentError => e
puts "An exception was raised with the message: #{e.message}"
end
########################################################
########################################################
# example of a method that yields an implicit block
arr = [1, 2, 3]
def map!(arr)
for i in 0..(arr.length - 1) do
arr[i] = yield arr[i]
end
end
map!(arr) do |item|
item * 5
end
puts "arr after map! #{arr} via implicit block"
########################################################
########################################################
# example of a method that calls an explicit block param
arr = [1, 2, 3]
def map!(arr, &block)
for i in 0..(arr.length - 1) do
arr[i] = block.call(arr[i])
end
end
map!(arr) do |item|
item * 5
end
puts "arr after map! #{arr} via explicit block param"
########################################################
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment