Created
February 19, 2016 17:58
-
-
Save jlogsdon/5704c366989538ff934f to your computer and use it in GitHub Desktop.
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
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