Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda Behaviour

Tags:

ruby

lambda

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" ?

like image 492
Discorick Avatar asked Dec 12 '12 21:12

Discorick


2 Answers

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.

like image 61
Peter Avatar answered Sep 19 '22 04:09

Peter


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.

like image 45
user1118597 Avatar answered Sep 19 '22 04:09

user1118597