I am having difficulty understanding what makes the following behaviour possible (taken from the ruby pickaxe book):
def power_proc_generator
value = 1
lambda {value += value}
end
power_proc = power_proc_generator
3.times {puts power_proc.call} # => 2,4,8
3.times {puts power_proc_generator.call()} # => 2,2,2
I don't see how the "power_proc" object allows the value to continue doubling as I would assume (wrongly it seems) that each call would reassign value to 1.
My question being why does "3.times {puts power_proc.call}" result "2,4,8" and not "2,2,2" ?
power_proc_generator
returns a lambda which uses (and modifies) the value of a variable in the surrounding scope. This is known as a closure -- the returned function "closes" over the value of the value
variable. So each time you call the returned function, it multiplies value
by two. The important part is that value
stays around between calls to power_proc.call
, so you're modifying the existing variable.
Also, to elaborate on the difference between printing power_proc_generator
and power_proc.call
-- power_proc_generator
returns a new function each time it's called, which is why you never see value
being increased. power_proc.call
, on the other hand, continues calling the same function multiple times.
power_proc_generator returns a lambda that includes a closure that contains the variable 'value'. So that variable hangs around from one power_proc.call to the next.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With