# Blocks and scoping question

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?

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

A friend informs me that this is changed in 1.9

For this who are interested:

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?

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.

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
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.

From: Mischa F. [mailto:[email protected]]

# …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