# Closures 101

**URL:** <https://www.ruby-forum.com/t/closures-101/131928>\
**Category:** Ruby\
**Created:** [March 14, 2008, 2:11pm UTC](https://www.ruby-forum.com/t/closures-101/131928 "2008-03-14T14:11:06Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 14, 2008, 2:11pm UTC](https://www.ruby-forum.com/t/closures-101/131928/1 "2008-03-14T14:11:06Z")

</div>

class Object  
def singleton\_class  
class \<\< self  
self  
end  
end  
end

data = Object.new  
status = “good”  
data.singleton\_class.class\_eval {  
define\_method(:status) {  
status  
}  
}  
p data.status # =\> “good”  
status = “bad”  
p data.status # =\> “bad”

I have a decent amount of experience with ruby, but I have somehow  
misunderstood closures this whole time. I thought a closure contained  
a full “snapshot” of the stack, but actually it contains references to  
the stack. That is, I thought \<\<status = “bad”\>\> would have no  
effect.

This came about from the following situation:

def add\_status(array)  
index = 0  
while index \< array.size  
status = “running #{index}”  
array[index].singleton\_class.class\_eval {  
define\_method(:status) {  
status  
}  
}  
index += 1  
end  
end

array = %w(a b c)  
add\_status(array)  
array.each { |elem| p elem.status }

# =\> “running 2”

# =\> “running 2”

# =\> “running 2”

If we replace “while index \< array.size” with “array.size.times do”  
then we get

# =\> “running 0”

# =\> “running 1”

# =\> “running 2”

So “times” uses a closure which in turn creates a new “status”  
variable, whereas the while loop does not use a closure and there is  
only one “status”.

I haven’t encountered this behavior before since I rarely use such  
uncouth imperative-style iterations. I’m not sure I have a point, per  
se, except that it’s possible to use ruby for a long time without  
fully understanding closures.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 14, 2008, 2:17pm UTC](https://www.ruby-forum.com/t/closures-101/131928/2 "2008-03-14T14:17:04Z")

</div>

Hi –

On Fri, 14 Mar 2008, removed\_email\_address@domain.invalid wrote:

> data.singleton\_class.class\_eval {  
> a full “snapshot” of the stack, but actually it contains references to  
> the stack. That is, I thought \<\<status = “bad”\>\> would have no  
> effect.

I think it’s best to think of the closure as preserving a binding. In  
that binding, the identifier “status” is bound to “bad”. If you  
reassign to status, you’re changing the binding of status inside the  
(overall) binding. The closure continues to reflect that binding.

David

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 14, 2008, 8:46pm UTC](https://www.ruby-forum.com/t/closures-101/131928/3 "2008-03-14T20:46:03Z")

</div>

update your blog!

-------------------------------------------------------|  
~ Ari  
Some people want love  
Others want money  
Me… Well…  
I just want this code to compile

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 14, 2008, 5:13pm UTC](https://www.ruby-forum.com/t/closures-101/131928/4 "2008-03-14T17:13:30Z")

</div>

Jeff

David explained it very properly. Maybe you might be interested to  
read more about it on my blog.  
I have written some code that allows to replace ivars with closures  
(idea stolen from Tom Christiansen’s famous Tom’s Object Tutorial in  
perl).  
This is much slower (about 5 to 10 !!) but might be of interest for  
thrade safety and the complete encapsulation (this was Tom’s  
motivation in the famous TOT)  
Anyway it is quite some read —\> [http://ruby-smalltalk.blogspot.com/](http://ruby-smalltalk.blogspot.com/)

## Cheers Robert

Whereof one cannot speak, thereof one must be silent.  
Ludwig Wittgenstein

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 15, 2008, 2:17am UTC](https://www.ruby-forum.com/t/closures-101/131928/5 "2008-03-15T02:17:41Z")

</div>

On Fri, Mar 14, 2008 at 8:45 PM, fedzor [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> update your blog!  
> ???  
> What’s wrong?
> 
> -------------------------------------------------------|  
> ~ Ari  
> Some people want love  
> Others want money  
> Me… Well…  
> I just want this code to compile

–  
[http://ruby-smalltalk.blogspot.com/](http://ruby-smalltalk.blogspot.com/)

* * *

Whereof one cannot speak, thereof one must be silent.  
Ludwig Wittgenstein

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 15, 2008, 4:23pm UTC](https://www.ruby-forum.com/t/closures-101/131928/6 "2008-03-15T16:23:01Z")

</div>

i would guess that they were saying:

good stuff on there.  
just not much and nothing recent.

take it as an encore! encore!

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [March 15, 2008, 5:13pm UTC](https://www.ruby-forum.com/t/closures-101/131928/7 "2008-03-15T17:13:43Z")

</div>

On Sat, Mar 15, 2008 at 4:21 PM, Sean A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> i would guess that they were saying:
> 
> good stuff on there.  
> just not much and nothing recent.
> 
> take it as an encore! encore!

## That’s very kind of you, but my head is empty and my schedule is full right now … ☹ Cheers Robert

[http://ruby-smalltalk.blogspot.com/](http://ruby-smalltalk.blogspot.com/)

* * *

Whereof one cannot speak, thereof one must be silent.  
Ludwig Wittgenstein
