# Problem with closure/block

**URL:** <https://www.ruby-forum.com/t/problem-with-closure-block/125526>\
**Category:** Ruby\
**Created:** [January 9, 2008, 10:45pm UTC](https://www.ruby-forum.com/t/problem-with-closure-block/125526 "2008-01-09T22:45:54Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 9, 2008, 10:45pm UTC](https://www.ruby-forum.com/t/problem-with-closure-block/125526/1 "2008-01-09T22:45:54Z")

</div>

###########################  
y=5  
print “y: " + y.to\_s + “\n”  
text\_at\_the\_end = lambda do |y|  
print y + " text at the end\n”  
end

print "y: " + y.to\_s + “\n”

def oneparam  
yield(“oneparam”)  
end

oneparam(&text\_at\_the\_end)  
print "y: " + y + “\n”

########################  
It gives the following output:

y: 5  
y: 5  
oneparam text at the end  
y: oneparam

Is this a bug? Shouldn’t “y” be in a local scope in “text\_at\_the\_end”?  
I just downloadad Ruby yesterday:

```
Ruby Version 1.8.6
Installer Version 186-26
```

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 10, 2008, 12:55am UTC](https://www.ruby-forum.com/t/problem-with-closure-block/125526/2 "2008-01-10T00:55:56Z")

</div>

On Jan 9, 3:42 pm, “removed\_email\_address@domain.invalid” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> yield(“oneparam”)  
> oneparam text at the end  
> y: oneparam
> 
> Is this a bug? Shouldn’t “y” be in a local scope in “text\_at\_the\_end”?  
> I just downloadad Ruby yesterday:
> 
> ```
> Ruby Version 1.8.6
> Installer Version 186-26
> 
> ```

There are past threads that discuss this, but, basically, no, it’s not  
a bug, that’s just how Ruby does it.

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 10, 2008, 1:01am UTC](https://www.ruby-forum.com/t/problem-with-closure-block/125526/3 "2008-01-10T01:01:46Z")

</div>

On Jan 9, 4:42 pm, “removed\_email\_address@domain.invalid” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> yield(“oneparam”)  
> oneparam text at the end  
> y: oneparam
> 
> Is this a bug? Shouldn’t “y” be in a local scope in “text\_at\_the\_end”?  
> I just downloadad Ruby yesterday:
> 
> ```
> Ruby Version 1.8.6
> Installer Version 186-26
> 
> ```

“However, if at the time the block executes a local variable  
already exists with the same name as that of a variable in  
the block, the existing local variable will be used in the  
block. Its value will therefore be available after the block  
finishes.”

“Programming Ruby” p. 106

Whether this is a “bug” or a “feature” is in the eye of the beholder,  
but it is something you should be aware of.

Has this changed in 1.9, or is it anticipated to change in 2.0 ?

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 10, 2008, 1:36am UTC](https://www.ruby-forum.com/t/problem-with-closure-block/125526/4 "2008-01-10T01:36:51Z")

</div>

> Has this changed in 1.9, or is it anticipated to change in 2.0 ?

With small change (added .to\_s method)

$ cat proc.rb  
###########################  
y=5  
print “y: " + y.to\_s + “\n”  
text\_at\_the\_end = lambda do |y|  
print y + " text at the end\n”  
end

print "y: " + y.to\_s + “\n”

def oneparam  
yield(“oneparam”)  
end

oneparam(&text\_at\_the\_end)  
print "y: " + y.to\_s + “\n”

########################

$ ruby1.8 proc.rb  
y: 5  
y: 5  
oneparam text at the end  
y: oneparam

## $ ruby1.9 proc.rb y: 5 y: 5 oneparam text at the end y: 5

Rados³aw Bu³at

[http://radarek.jogger.pl](http://radarek.jogger.pl) - mój blog

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 10, 2008, 2:33am UTC](https://www.ruby-forum.com/t/problem-with-closure-block/125526/5 "2008-01-10T02:33:34Z")

</div>

removed\_email\_address@domain.invalid wrote:

> def oneparam  
> y: 5  
> y: 5  
> oneparam text at the end  
> y: oneparam
> 
> Is this a bug? Shouldn’t “y” be in a local scope in “text\_at\_the\_end”?  
> I just downloadad Ruby yesterday:
> 
> ```
> Ruby Version 1.8.6
> Installer Version 186-2
> 
> ```

Blocks in Ruby are closures, so they save the context in which they were  
created, but new variables inside the closure are local.

irb(main):001:0\> x = 1  
=\> 1  
irb(main):002:0\> l = lambda do |y|  
irb(main):003:1\* puts x  
irb(main):004:1\> puts y  
irb(main):005:1\> end  
=\> #Proc:0x00002ae970650e58@:2(irb)  
irb(main):006:0\> l[‘hello’]  
1  
hello  
=\> nil  
irb(main):007:0\> y  
NameError: undefined local variable or method `y’ for main:Object  
from (irb):7  
from :0  
irb(main):008:0\> x  
=\> 1  
irb(main):009:0\> x += 1  
=\> 2  
irb(main):010:0\> l[‘again’]  
2  
again  
=\> nil

Take a look here:  
[http://ruby-doc.org/docs/ProgrammingRuby/html/tut\_containers.html#UG](http://ruby-doc.org/docs/ProgrammingRuby/html/tut_containers.html#UG)

-Justin

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 10, 2008, 9:15am UTC](https://www.ruby-forum.com/t/problem-with-closure-block/125526/6 "2008-01-10T09:15:49Z")

</div>

"Blocks in Ruby are closures, so they save the context in which they  
were  
created, but new variables inside the closure are local. "

I just expected, that if the head of the closure has x, it will create  
a new local variable with the same name.

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 10, 2008, 6:47pm UTC](https://www.ruby-forum.com/t/problem-with-closure-block/125526/7 "2008-01-10T18:47:22Z")

</div>

On 1/9/08, Rados³aw Bu³at [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> end
> 
> y: 5  
> y: 5  
> oneparam text at the end  
> y: 5

And if you use the -w option ruby 1.9 will warn that the semantics have  
changed.

$ ruby1.9 -w proc.rb  
proc.rb:4: warning: shadowing outer local variable - y  
y: 5  
y: 5  
oneparam text at the end  
y: 5

$ ruby -w proc.rb  
y: 5  
y: 5  
oneparam text at the end  
y: oneparam

–  
Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 11, 2008, 6:25pm UTC](https://www.ruby-forum.com/t/problem-with-closure-block/125526/8 "2008-01-11T18:25:56Z")

</div>

On Jan 10, 9:13 am, “removed\_email\_address@domain.invalid” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > ###########################  
> > > end  
> > > y: oneparam  
> > > irb(main):001:0\> x = 1  
> > > irb(main):007:0\> y  
> > > =\> nil
> 
> > Take a look here:[Programming Ruby: The Pragmatic Programmer's Guide](http://ruby-doc.org/docs/ProgrammingRuby/html/tut_containers.html#UG)
> 
> > -Justin

I think it’s an advantage in javascript, that you have to mark new  
variables with “var”, so the scope of a variable is always obvious.

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 12, 2008, 7:58am UTC](https://www.ruby-forum.com/t/problem-with-closure-block/125526/9 "2008-01-12T07:58:39Z")

</div>

> I think it’s an advantage in javascript, that you have to mark new  
> variables with “var”, so the scope of a variable is always obvious.

JS doesn’t have it right… if anything, I’ve seen it cause MUCH MORE  
confusion wrt closures.  
‘var’ is context-specific (only applies INSIDE functions, but  
syntactically valid outside) and it is just a hint, not a declaration.  
These are the same:

function a(z) { var x = z; return function () {return x} }  
function b(z) { x = z; return function () {return x}; var x }

and:

var x = 10; // outside a function

is both misleading and useless.
