# How does ruby handle scope and closure in this case?

**URL:** <https://www.ruby-forum.com/t/how-does-ruby-handle-scope-and-closure-in-this-case/113341>\
**Category:** Ruby\
**Created:** [August 30, 2007, 2:25am UTC](https://www.ruby-forum.com/t/how-does-ruby-handle-scope-and-closure-in-this-case/113341 "2007-08-30T02:25:56Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![grocery\_stocker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/e9c0ed/32.png) [@grocery\_stocker](https://www.ruby-forum.com/u/grocery_stocker)\
**Post date:** [August 30, 2007, 2:25am UTC](https://www.ruby-forum.com/t/how-does-ruby-handle-scope-and-closure-in-this-case/113341/1 "2007-08-30T02:25:56Z")

</div>

How come when I do something like

#!/usr/bin/ruby -w

def n\_times(thing)  
return thing  
end

pi = n\_times(23);  
puts pi

the variable ‘thing’ doesn’t go out of scope.

But when I do something like

#!/usr/bin/ruby

def n\_times(thing)  
return lambda{|n| thing \* n}  
end

pi = n\_times(23);  
puts pi.call(2)

The varialble ‘thing’ does go out of scope.

---

<div class="post-metadata">

**Author:** ![grocery\_stocker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/e9c0ed/32.png) [@grocery\_stocker](https://www.ruby-forum.com/u/grocery_stocker)\
**Post date:** [August 30, 2007, 2:49am UTC](https://www.ruby-forum.com/t/how-does-ruby-handle-scope-and-closure-in-this-case/113341/2 "2007-08-30T02:49:56Z")

</div>

Hi,

I think it’s a excution stack thing, you should look a the C code if you  
want to understand ruby magic.

Hope I got your question, otherwise the text you got this example from  
describes fairly good why the ‘thing’ (or aThing) variable ‘gets’ out of  
scope (its refence is still hold by the Proc object).

Even in the first case you should got the Object out of scope since you  
passed the reference:

def n\_times(thing)  
puts thing.object\_id  
return thing  
end

pi = n\_times(23)  
puts pi.object\_id

Regards  
Florian

---

<div class="post-metadata">

**Author:** ![grocery\_stocker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/e9c0ed/32.png) [@grocery\_stocker](https://www.ruby-forum.com/u/grocery_stocker)\
**Post date:** [August 30, 2007, 3:23am UTC](https://www.ruby-forum.com/t/how-does-ruby-handle-scope-and-closure-in-this-case/113341/3 "2007-08-30T03:23:00Z")

</div>

On Aug 29, 2007, at 8:25 PM, grocery\_stocker wrote:

> the variable ‘thing’ doesn’t go out of scope.

I think it does. The variable ‘thing’ from #n\_times is not visible at  
top level. If you were to do

```
puts thing

```

at this point, you would get an error.

Regards, Morton

---

<div class="post-metadata">

**Author:** ![grocery\_stocker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/e9c0ed/32.png) [@grocery\_stocker](https://www.ruby-forum.com/u/grocery_stocker)\
**Post date:** [August 30, 2007, 5:39am UTC](https://www.ruby-forum.com/t/how-does-ruby-handle-scope-and-closure-in-this-case/113341/4 "2007-08-30T05:39:45Z")

</div>

Florian AÃŸmann wrote:

> Hi,
> 
> I think it’s a excution stack thing, you should look a the C code if you  
> want to understand ruby magic.
> 
> Hope I got your question, otherwise the text you got this example from  
> describes fairly good why the ‘thing’ (or aThing) variable ‘gets’ out of  
> scope (its refence is still hold by the Proc object).
> 
> Even in the first case you should got the Object out of scope since you  
> passed the reference:
> 
> def n\_times(thing)  
> puts thing.object\_id  
> return thing  
> end
> 
> pi = n\_times(23)  
> puts pi.object\_id
> 
> Regards  
> Florian

This example will give a false impression. Fixnum’s always have the  
same ID regardless of scope. try this smae test with something other  
then a small integer:

var = n\_times(Object.new)  
puts var.object\_id

It will give you a much better sense of what is going on.

John M.

---

<div class="post-metadata">

**Author:** ![grocery\_stocker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/e9c0ed/32.png) [@grocery\_stocker](https://www.ruby-forum.com/u/grocery_stocker)\
**Post date:** [August 31, 2007, 11:49am UTC](https://www.ruby-forum.com/t/how-does-ruby-handle-scope-and-closure-in-this-case/113341/5 "2007-08-31T11:49:59Z")

</div>

2007/8/30, grocery\_stocker [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> pi = n\_times(23);  
> puts pi.call(2)
> 
> The varialble ‘thing’ does go out of scope.

Does it?

$ ruby\<\<XXX

> def n\_times(thing)  
> return lambda{|n| thing \* n}  
> end
> 
> pi = n\_times(23);  
> puts pi.call(2)  
> puts thing  
> XXX  
> 46  
> -:7: undefined local variable or method `thing’ for main:Object  
> (NameError)

Ruby has static scoping rules but, err, can’t remember the proper  
term, dynamic binding. When you create the lambda you create a  
closure which keeps references in its environment alive.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![grocery\_stocker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/e9c0ed/32.png) [@grocery\_stocker](https://www.ruby-forum.com/u/grocery_stocker)\
**Post date:** [August 31, 2007, 12:55pm UTC](https://www.ruby-forum.com/t/how-does-ruby-handle-scope-and-closure-in-this-case/113341/6 "2007-08-31T12:55:21Z")

</div>

On 8/31/07, Robert K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > puts pi  
> > end  
> > def n\_times(thing)  
> > Ruby has static scoping rules but, err, can’t remember the proper  
> > term, dynamic binding. When you create the lambda you create a  
> > closure which keeps references in its environment alive.
> 
> Kind regards
> 
> robert

Hmm it might be a case where object and variable could easily get  
confused, I have jotted down a little example which, I hope, shows  
what is going on here:

------------------ 8\< ----------------  
def a param  
proc { param \<\< “.” }  
end  
def b param  
proc { param = param + “.” }  
end

o = “42”  
p = a o  
q = a o  
puts p.call  
puts p.call  
puts q.call  
puts o

–\>42.  
–\>42…  
–\>42…  
–\>42…

o = “42”  
p = b o  
q = b o  
puts p.call  
puts p.call  
puts q.call  
puts o  
–\>42.  
–\>42…  
–\>42.  
–\>42

Cheers  
Robert
