Blocks and Methods
Proc Lambda
Proc and lambda objects store callable behavior in variables.
callable object
A callable object can be assigned to a variable and later invoked with `call`.
Proc Lambda
proc_lambda.rb
Replay: real traced execution (multi-file project)
base = 4
doubler = Proc.new do |value|
value * 2
end
labeler = lambda do |value|
"value=#{value}"
end
result = doubler.call(base)
label = labeler.call(result)
puts "base=#{base}"
puts label
base = 2
doubler = Proc.new do |value|
value * 2
end
labeler = lambda do |value|
"value=#{value}"
end
result = doubler.call(base)
label = labeler.call(result)
puts "base=#{base}"
puts label
base = 8
doubler = Proc.new do |value|
value * 2
end
labeler = lambda do |value|
"value=#{value}"
end
result = doubler.call(base)
label = labeler.call(result)
puts "base=#{base}"
puts label
base ← 4, doubler ← ⟨Proc A /tmp/execution/⟨tmp B⟩.rb:33⟩, labeler ← ⟨Proc C /tmp/execution/⟨tmp B⟩.rb:48 (lambda)⟩
1base→ 4 = 4 #@base=2, 823doubler→ ⟨Proc A /tmp/execution/⟨tmp B⟩.rb:33⟩ = Proc.new do |value|4 value * 25end67labeler→ ⟨Proc C /tmp/execution/⟨tmp B⟩.rb:48 (lambda)⟩ = lambda do |value|8 "value=#{value}"9end1011result = doubler.call(base)812label = labeler.call(result)do |value|
3doubler = Proc.new do |value4|4 value * 25endresult ← 8
11result→ 8 = doubler.call(base)812label = labeler.call(result)value=8do |value|
7labeler = lambda do |value8|8 "value=#{value}"9endlabel ← value=8
11result = doubler.call(base)12label→ value=8 = labeler.call(result)value=81314puts "base=#{base4}"15puts labelvalue=8outputbase=4 value=8
base ← 2, doubler ← ⟨Proc A /tmp/execution/⟨tmp B⟩.rb:33⟩, labeler ← ⟨Proc C /tmp/execution/⟨tmp B⟩.rb:48 (lambda)⟩
1base→ 2 = 223doubler→ ⟨Proc A /tmp/execution/⟨tmp B⟩.rb:33⟩ = Proc.new do |value|4 value * 25end67labeler→ ⟨Proc C /tmp/execution/⟨tmp B⟩.rb:48 (lambda)⟩ = lambda do |value|8 "value=#{value}"9end1011result = doubler.call(base)412label = labeler.call(result)do |value|
3doubler = Proc.new do |value2|4 value * 25endresult ← 4
11result→ 4 = doubler.call(base)412label = labeler.call(result)value=4do |value|
7labeler = lambda do |value4|8 "value=#{value}"9endlabel ← value=4
11result = doubler.call(base)12label→ value=4 = labeler.call(result)value=41314puts "base=#{base2}"15puts labelvalue=4outputbase=2 value=4
base ← 8, doubler ← ⟨Proc A /tmp/execution/⟨tmp B⟩.rb:33⟩, labeler ← ⟨Proc C /tmp/execution/⟨tmp B⟩.rb:48 (lambda)⟩
1base→ 8 = 823doubler→ ⟨Proc A /tmp/execution/⟨tmp B⟩.rb:33⟩ = Proc.new do |value|4 value * 25end67labeler→ ⟨Proc C /tmp/execution/⟨tmp B⟩.rb:48 (lambda)⟩ = lambda do |value|8 "value=#{value}"9end1011result = doubler.call(base)1612label = labeler.call(result)do |value|
3doubler = Proc.new do |value8|4 value * 25endresult ← 16
11result→ 16 = doubler.call(base)1612label = labeler.call(result)value=16do |value|
7labeler = lambda do |value16|8 "value=#{value}"9endlabel ← value=16
11result = doubler.call(base)12label→ value=16 = labeler.call(result)value=161314puts "base=#{base8}"15puts labelvalue=16outputbase=8 value=16
Follow the Calls
basestarts as4.doubler.call(base)returns8.labeler.call(8)builds the textvalue=8.- The program prints
base=4andvalue=8. | call | input | result | | --- | --- | --- | |doubler| 4 | 8 | |labeler| 8 | value=8 |
Exercise: proc_lambda.rb
Reproduce base=4 and value=8, then use the pinned base variants to predict value=4 and value=16.