22 | Chapter 1: Foundational Techniques
lambda_proc.call # => 3
proc_new_proc.call # =>
puts "Never reached"
end
block_test # => 4
The return statement in lambda_proc returns the value 3 from the lambda. Conversely,
the return statement in proc_new_proc returns from the calling function, block_test??”
thus, the value 4 is returned from block_test. The puts statement is never executed,
because the proc_new_proc.call statement returns from block_test first.
Blocks can also be converted to Procs by passing them to a function, using & in the
function??™s formal parameters:
def some_function(&b)
puts "Block is a #{b} and returns #{b.call}"
end
some_function { 6 + 3 }
# >> Block is a #
and returns 9
Conversely, you can also substitute a Proc with & when a function expects a block:
add_3 = lambda {|x| x+3}
(1..5).map(&add_3) # => [4, 5, 6, 7, 8]
Closures
Closures are created when a block or Proc accesses variables defined outside of its
scope. Even though the containing block may go out of scope, the variables are kept
around until the block or Proc referencing them goes out of scope. A simplistic example,
though not practically useful, demonstrates the idea:
def get_closure
data = [1, 2, 3]
lambda { data }
end
block = get_closure
block.call # => [1, 2, 3]
The anonymous function (the lambda) returned from get_closure references the local
variable data, which is defined outside of its scope.
Pages:
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49