I came across this code:
squareIt = Proc.new do |x|
x * x
end
doubleIt = Proc.new do |x|
x + x
end
def compose proc1, proc2
Proc.new do |x|
proc2.call(proc1.call(x))
end
end
doubleThenSquare = compose(doubleIt, squareIt)
squareThenDouble = compose(squareIt, doubleIt)
doubleThenSquare.call(5)
squareThenDouble.call(5)
doubleThenSquare
is called with 5
. doubleThenSquare
is equal to the return value of compose
, which has its two parameters doubleIt
and squareIt
passed.
I don't see how 5
is passed all its way into the different procs Proc.new do |x|
. How does it know what x
is in each case?
Let's step through it.
doubleIt = Proc.new do |x|
x + x
end
#=> #<Proc:0x00000002326e08@(irb):1429>
squareIt = Proc.new do |x|
x * x
end
#=> #<Proc:0x00000002928bf8@(irb):1433>
proc1 = doubleIt
proc2 = squareIt
compose
returns the proc proc3
.
proc3 = Proc.new do |x|
proc2.call(proc1.call(x))
end
#=> #<Proc:0x000000028e7608@(irb):1445>
proc3.call(x)
is executed in the same way as
proc3_method(x)
where
def proc3_method(x)
y = proc1.call(x)
proc2.call(y)
end
When x = 5
,
y = proc1.call(5)
#=> 10
proc2.call(10)
#=> 100
proc3_method(5)
therefore returns 100
, as does proc3.call(5)
.