# Blocks and scoping question

**URL:** <https://www.ruby-forum.com/t/blocks-and-scoping-question/148286>\
**Category:** Ruby\
**Created:** [September 11, 2008, 10:19am UTC](https://www.ruby-forum.com/t/blocks-and-scoping-question/148286 "2008-09-11T10:19:04Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![mischa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b9bd4f/32.png) [@mischa](https://www.ruby-forum.com/u/mischa)\
**Post date:** [September 11, 2008, 10:19am UTC](https://www.ruby-forum.com/t/blocks-and-scoping-question/148286/1 "2008-09-11T10:19:04Z")

</div>

Hello,

The following makes sense to me:

lambda {|x| puts x; [1,2].collect{|x| x+1} }.call(“aaa”)  
aaa  
=\> [2, 3]

The following does not so much:

lambda {|x| puts x; [1,2].collect{|x| x+1}; puts x }.call(“aaa”)  
aaa  
2  
=\> nil

Why is the final puts x not return a?

---

<div class="post-metadata">

**Author:** ![mischa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b9bd4f/32.png) [@mischa](https://www.ruby-forum.com/u/mischa)\
**Post date:** [September 11, 2008, 10:24am UTC](https://www.ruby-forum.com/t/blocks-and-scoping-question/148286/2 "2008-09-11T10:24:04Z")

</div>

On Thursday 11 September 2008, Mischa F. wrote:

> lambda {|x| puts x; [1,2].collect{|x| x+1}; puts x }.call(“aaa”)  
> aaa  
> 2  
> =\> nil
> 
> Why is the final puts x not return a?

Because puts always returns nil:

ri IO#puts

## ---------------------------------------------------------------- IO#puts ios.puts(obj, …) =\> nil

Stefano

---

<div class="post-metadata">

**Author:** ![mischa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b9bd4f/32.png) [@mischa](https://www.ruby-forum.com/u/mischa)\
**Post date:** [September 11, 2008, 10:24am UTC](https://www.ruby-forum.com/t/blocks-and-scoping-question/148286/3 "2008-09-11T10:24:40Z")

</div>

A friend informs me that this is changed in 1.9

For this who are interested:

[http://groups.google.com/group/sbonrails/browse\_thread/thread/cfcfdad71d8f786c](http://groups.google.com/group/sbonrails/browse_thread/thread/cfcfdad71d8f786c)

Mischa F. wrote:

> Hello,
> 
> The following makes sense to me:
> 
> lambda {|x| puts x; [1,2].collect{|x| x+1} }.call(“aaa”)  
> aaa  
> =\> [2, 3]
> 
> The following does not so much:
> 
> lambda {|x| puts x; [1,2].collect{|x| x+1}; puts x }.call(“aaa”)  
> aaa  
> 2  
> =\> nil
> 
> Why is the final puts x not return a?

---

<div class="post-metadata">

**Author:** ![mischa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b9bd4f/32.png) [@mischa](https://www.ruby-forum.com/u/mischa)\
**Post date:** [September 11, 2008, 10:26am UTC](https://www.ruby-forum.com/t/blocks-and-scoping-question/148286/4 "2008-09-11T10:26:29Z")

</div>

Stefano C. wrote:

> On Thursday 11 September 2008, Mischa F. wrote:
> 
> > lambda {|x| puts x; [1,2].collect{|x| x+1}; puts x }.call(“aaa”)  
> > aaa  
> > 2  
> > =\> nil
> > 
> > Why is the final puts x not return a?
> 
> Because puts always returns nil:
> 
> ri IO#puts
> 
> ## ---------------------------------------------------------------- IO#puts ios.puts(obj, …) =\> nil
> 
> Stefano

Sorry, phrased this wrong, i wasn’t looking at the return value, but the  
2 above it.

---

<div class="post-metadata">

**Author:** ![mischa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b9bd4f/32.png) [@mischa](https://www.ruby-forum.com/u/mischa)\
**Post date:** [September 11, 2008, 10:41am UTC](https://www.ruby-forum.com/t/blocks-and-scoping-question/148286/5 "2008-09-11T10:41:05Z")

</div>

Mischa F. wrote:

> Hello,
> 
> The following makes sense to me:
> 
> lambda {|x| puts x; [1,2].collect{|x| x+1} }.call(“aaa”)  
> aaa  
> =\> [2, 3]
> 
> The following does not so much:
> 
> lambda {|x| puts x; [1,2].collect{|x| x+1}; puts x }.call(“aaa”)  
> aaa  
> 2  
> =\> nil
> 
> Why is the final puts x not return a?

It’s because the x in collect{|x| …} in fact uses the variable x that  
previously contained your “aaa”, because it is already defined in this  
scope. If x wasn’t defined at the point of calling collect, then x  
inside collect’s block would be a separate variable each iteration.

This is going to change in Ruby 1.9, and block variables will always be  
separate from variables visible in the scope.

TPR.

---

<div class="post-metadata">

**Author:** ![mischa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b9bd4f/32.png) [@mischa](https://www.ruby-forum.com/u/mischa)\
**Post date:** [September 11, 2008, 10:39am UTC](https://www.ruby-forum.com/t/blocks-and-scoping-question/148286/6 "2008-09-11T10:39:18Z")

</div>

From: Mischa F. [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]

# …but the 2 above it.

compare,

C:\family\ruby\>ruby -ve “lambda{|x| puts x;[1,2].collect{|x| x+1}; puts  
x }.call  
(‘aaa’)”  
ruby 1.8.6 (2008-08-11 patchlevel 287) [i386-mswin32]  
aaa  
2

C:\family\ruby\>\ruby187\bin\ruby -ve “lambda{|x| puts  
x;[1,2].collect{|x| x+1};  
puts x }.call(‘aaa’)”  
ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-mswin32]  
aaa  
2

C:\family\ruby\>\ruby1.9\bin\ruby -ve “lambda{|x| puts  
x;[1,2].collect{|x| x+1};  
puts x }.call(‘aaa’)”  
ruby 1.9.0 (2008-06-20 revision 17482) [i386-mswin32]  
-e:1: warning: shadowing outer local variable - x  
aaa  
aaa
