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_generatorreturns 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 thevaluevariable. So each time you call the returned function, it multipliesvalueby two. The important part is thatvaluestays around between calls topower_proc.call, so you’re modifying the existing variable.Also, to elaborate on the difference between printing
power_proc_generatorandpower_proc.call—power_proc_generatorreturns a new function each time it’s called, which is why you never seevaluebeing increased.power_proc.call, on the other hand, continues calling the same function multiple times.