# What am I missing with this closure example?

**URL:** <https://www.ruby-forum.com/t/what-am-i-missing-with-this-closure-example/54303>\
**Category:** Ruby\
**Created:** [March 1, 2006, 3:11am UTC](https://www.ruby-forum.com/t/what-am-i-missing-with-this-closure-example/54303 "2006-03-01T03:11:51Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [March 1, 2006, 3:11am UTC](https://www.ruby-forum.com/t/what-am-i-missing-with-this-closure-example/54303/1 "2006-03-01T03:11:51Z")

</div>

Hello!

Since my last question about  
closure([http://groups.google.com/group/comp.lang.ruby/browse\_frm/thread/0d7e258107e1683e/12e182a6ff493232?hl=en#12e182a6ff493232](http://groups.google.com/group/comp.lang.ruby/browse_frm/thread/0d7e258107e1683e/12e182a6ff493232?hl=en#12e182a6ff493232))  
I am testing my understanding making some examples.

Here’s some code:

def f name  
x = 0

```
case name
	when "one"
		lambda {x += 1; puts x}
	when "two"
		lambda {puts x}
end

```

end

one = f “one”  
two = f “two”

one.call  
two.call  
one.call  
two.call

Result:

1  
0  
2  
0

I expected the following.  
1  
1  
2  
2

I thought that x is shared between one and two but they don’t seem to.  
Or am I missing something?

Thanks.

Sam

---

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [March 1, 2006, 3:23am UTC](https://www.ruby-forum.com/t/what-am-i-missing-with-this-closure-example/54303/2 "2006-03-01T03:23:56Z")

</div>

On 28-Feb-06, at 8:58 PM, Sam K. wrote:

> x = 0  
> two = f “two”  
> 2  
> I thought that x is shared between one and two but they don’t seem to.  
> Or am I missing something?

Each time you call f you get a different x, so the lambda’s x are  
bound to different variables. Does this do what you expect:

def f  
x = 0

[lambda {x += 1; puts x}, lambda {puts x}]  
end

one, two = f

one.call  
two.call  
one.call  
two.call

Mike

–

Mike S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
[http://www.stok.ca/~mike/](http://www.stok.ca/~mike/)

The “`Stok’ disclaimers” apply.

---

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [August 3, 2006, 1:46pm UTC](https://www.ruby-forum.com/t/what-am-i-missing-with-this-closure-example/54303/3 "2006-08-03T13:46:17Z")

</div>

Like konsu states, you have two different closures. Here’s a little  
rewrite of your code that works with one closure.

def f  
x = 0  
one = lambda {x += 1; puts x}  
two = lambda {puts x}  
[one, two]  
end

one, two = f

one.call  
two.call  
one.call  
two.call

=\> with results of  
1  
1  
2  
2

- Hitesh  
[http://www.jasani.org/](http://www.jasani.org/)

---

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [August 15, 2006, 2:09pm UTC](https://www.ruby-forum.com/t/what-am-i-missing-with-this-closure-example/54303/4 "2006-08-15T14:09:55Z")

</div>

“Sam K.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

> def f name  
> x = 0

> case name  
> when “one”  
> lambda {x += 1; puts x}  
> when “two”  
> lambda {puts x}  
> end  
> end

> one = f “one”  
> two = f “two”

The assignment “x = 0” gets executed every time you call f, creating a  
new x  
each time and initializing that new x to zero.

As far as I can tell, Ruby has no static scope, only dynamic scope,  
which,  
if I’m right, means there’s no straightforward way to do what you’re  
trying.

In Perl, for instance, you could do this:

{  
my $x = 0;  
sub f  
{  
my $name = shift;  
return sub { $x += 1; print “$x\n”; } if ($name eq ‘one’);  
return sub { print “$x\n”; } if ($name eq ‘two’);  
}  
}  
my $one = f(‘one’);  
my $two = f(‘two’);  
$one-\>();  
$two-\>();  
$one-\>();  
$two-\>();

And achieve the result you expected, but in Ruby, I don’t know how to  
achieve  
something similar. As a practical matter, I would just create an object  
with  
an attribute and use methods on that object in lieu of the closures.

---

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [August 3, 2006, 2:22pm UTC](https://www.ruby-forum.com/t/what-am-i-missing-with-this-closure-example/54303/5 "2006-08-03T14:22:19Z")

</div>

removed\_email\_address@domain.invalid wrote:

> one, two = f  
> 2  
> 2

Aha~  
Now I see the difference.  
Thanks everyone.

Sam

---

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [August 15, 2006, 2:09pm UTC](https://www.ruby-forum.com/t/what-am-i-missing-with-this-closure-example/54303/6 "2006-08-15T14:09:57Z")

</div>

hello,

f(“two”) creates a lambda that sees ‘x’ as it was at the time of its  
creation. zero that is.

the ‘x’ that f(“one”) uses is in a different closure.

konstantin

“Sam K.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote in message  
news:removed\_email\_address@domain.invalid…
