# That was unexpected -- strange scoping behavior

**URL:** <https://www.ruby-forum.com/t/that-was-unexpected-strange-scoping-behavior/149045>\
**Category:** Ruby\
**Created:** [September 19, 2008, 7:17pm UTC](https://www.ruby-forum.com/t/that-was-unexpected-strange-scoping-behavior/149045 "2008-09-19T19:17:11Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![oldbug](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/c0e974/32.png) [@oldbug](https://www.ruby-forum.com/u/oldbug)\
**Post date:** [September 19, 2008, 7:17pm UTC](https://www.ruby-forum.com/t/that-was-unexpected-strange-scoping-behavior/149045/1 "2008-09-19T19:17:11Z")

</div>

Consider the following piece of code:  
#!/usr/bin/env ruby

def wow(idx, donetest)  
until donetest.call(idx)  
puts idx  
idx = idx + 1  
end #until  
end #def wow

idx = 2  
puts “before wow, idx = #{idx}\n”  
wow(3, lambda {|x| x \> 5})  
puts “after wow, idx = #{idx}\n”

# Now, suppose I used a different dummy variable for the lambda function

puts “before wow, idx = #{idx}\n”  
wow(3, lambda {|idx| idx \> 5})  
puts “after wow, idx = #{idx}\n”

* * *

When I just happened to use the name “idx” for my dummy variable in my  
lambda function, I was quite surprised to learn that it changed the  
value of “idx” in the enclosing scope. I suppose that makes sense  
(given Ruby’s scoping rules), but it sure was unexpected!

–wpd

---

<div class="post-metadata">

**Author:** ![oldbug](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/c0e974/32.png) [@oldbug](https://www.ruby-forum.com/u/oldbug)\
**Post date:** [September 19, 2008, 7:35pm UTC](https://www.ruby-forum.com/t/that-was-unexpected-strange-scoping-behavior/149045/2 "2008-09-19T19:35:31Z")

</div>

Patrick D. wrote:

> Consider the following piece of code:  
> #!/usr/bin/env ruby
> 
> def wow(idx, donetest)  
> until donetest.call(idx)  
> puts idx  
> idx = idx + 1  
> end #until  
> end #def wow
> 
> idx = 2  
> puts “before wow, idx = #{idx}\n”  
> wow(3, lambda {|x| x \> 5})  
> puts “after wow, idx = #{idx}\n”
> 
> # Now, suppose I used a different dummy variable for the lambda function
> 
> puts “before wow, idx = #{idx}\n”  
> wow(3, lambda {|idx| idx \> 5})  
> puts “after wow, idx = #{idx}\n”
> 
> * * *
> 
> When I just happened to use the name “idx” for my dummy variable in my  
> lambda function, I was quite surprised to learn that it changed the  
> value of “idx” in the enclosing scope. I suppose that makes sense  
> (given Ruby’s scoping rules), but it sure was unexpected!
> 
> –wpd

Yes, it is a small gotcha. In Ruby 1.9 this is going to work like  
expected - lambda (or block) arguments will be separate from the lambda  
defining scope.

There will also be an option to declare additional local variables in  
lambdas. Ruby 1.8:

a=5  
[3].each{|x| a=x;puts a}  
a #=\> 3  
The a in the block refers to the outside a, and nothing can be done  
about this. This might sometimes cause errors, difficult to track down.  
If you don’t want the a in the block to refer to the a outside, you have  
to change the variable name.

Ruby 1.9:  
a=5  
[3].each{|x;a| a=x;puts a}  
a #=\> 5

After semicolon, you can define variables that will be local in their  
block or lambda, even despite name clash.

TPR.

---

<div class="post-metadata">

**Author:** ![oldbug](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/c0e974/32.png) [@oldbug](https://www.ruby-forum.com/u/oldbug)\
**Post date:** [September 19, 2008, 7:43pm UTC](https://www.ruby-forum.com/t/that-was-unexpected-strange-scoping-behavior/149045/3 "2008-09-19T19:43:05Z")

</div>

Interesting. So I suppose that means that there’s a hole in Ruby’s  
implementation of lexical scoping…? It’s sort of reminiscent of the  
problems people run into with non-hygienic macros in Lisp dialects.

---

<div class="post-metadata">

**Author:** ![oldbug](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/c0e974/32.png) [@oldbug](https://www.ruby-forum.com/u/oldbug)\
**Post date:** [September 19, 2008, 8:01pm UTC](https://www.ruby-forum.com/t/that-was-unexpected-strange-scoping-behavior/149045/4 "2008-09-19T20:01:17Z")

</div>

Dido S. wrote:

> Interesting. So I suppose that means that there’s a hole in Ruby’s  
> implementation of lexical scoping…? It’s sort of reminiscent of the  
> problems people run into with non-hygienic macros in Lisp dialects.

I guess, it’s rather not a hole in the implementation, but sort of a  
missed idea. The 1.8 behaviour is deterministic and documented, but  
discouraged because there’s no real need to use this as a feature, and  
it is not elegant because the lambda argument list “looks like” variable  
definition but is not, which makes the code harder to understand. And  
then the next step from ‘discouraged’ is ‘gone’, as we see in 1.9.

TPR.
