Skip to content

Instantly share code, notes, and snippets.

@jlogsdon
Created February 19, 2016 17:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jlogsdon/5704c366989538ff934f to your computer and use it in GitHub Desktop.
Save jlogsdon/5704c366989538ff934f to your computer and use it in GitHub Desktop.
require 'minitest/autorun'
class ProcAndLambdaTest < Minitest::Test
def setup
@arr = [ 1, 2, 3 ]
end
def test_basic_return_behavior
# NOTE: Defining methods like this actually hoists them into the instance. I'm doing this purely
# for organization of the tests.
def proc_return
Proc.new { return :early }.call
return :late
end
def lambda_return
lambda { return :early }.call
return :late
end
assert_equal proc_return, :early
assert_equal lambda_return, :late
end
def test_closure_argument_lists
def proc_closure
a = "from proc_closure"
Proc.new { |b| "#{a} with '#{b}'" }
end
def lambda_closure
a = "from lambda_closure"
-> (b) { "#{a} with '#{b}'" }
end
assert_equal "from proc_closure with ''", proc_closure.call
assert_equal "from proc_closure with 'passed'", proc_closure.call('passed')
assert_raises { lambda_closure.call }
assert_equal "from lambda_closure with 'passed'", lambda_closure.call('passed')
end
def test_block_return_vs_break
def block_each_return
@arr.each do |i|
return i if i == 2
end
return :end
end
# Procs and blocks can use next/break to skip an iteration or break out of the loop entirely
def block_each_break
@arr.each do |i|
break i if i == 2
end
return :end
end
assert_equal 2, block_each_return
assert_equal :end, block_each_break
end
def test_proc_as_block_return_vs_break
def proc_as_block_break
proc = Proc.new { |i| break i if i == 2 }
@arr.each(&proc)
return :end
end
def proc_as_block_return
proc = Proc.new { |i| return i if i == 2 }
@arr.each(&proc)
return :end
end
assert_raises { proc_as_block_break }
assert_equal 2, proc_as_block_return
end
def test_procy_curry_as_block
def proc_curry_as_block_return
proc = Proc.new { |a,i| return "#{a}#{i}" if i == 2 }
# Note that Proc#curry takes single argument denoting the arity of the curried proc. Actual
# arguments are provided with brackets. Check out the docs!
@arr.each(&(proc.curry['a']))
return :end
end
assert_equal "a2", proc_curry_as_block_return
end
def test_lambda_as_block_return_vs_break
# Lambdas as blocks, on the other hand, allow break, but it behaves the same as next
def lambda_as_block_break
lam = -> (i) { break if i == 2 }
@arr.each(&lam)
return :end
end
# Similar behavior with return using lambdas as blocks
def lambda_as_block_return
lam = -> (i) { return if i == 2 }
@arr.each(&lam)
return :end
end
assert_equal :end, lambda_as_block_return
assert_equal :end, lambda_as_block_break
end
def test_nested_procs
def procs_as_blocks_and_nested
@arr.each do |i|
Proc.new { |i| return i if i == 2 }.call
return i if i == 3
end
return :end
end
assert_equal 3, procs_as_blocks_and_nested
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment