Created
March 6, 2016 23:20
-
-
Save MrAlexLau/703aedad2dd62825fa5b to your computer and use it in GitHub Desktop.
Exploring Procs, blocks, and lambda expressions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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