Blocks and scoping question

M

Mischa Fierer

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?
 
S

Stefano Crocco

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?

Because puts always returns nil:

ri IO#puts

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

Mischa Fierer

Stefano said:
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

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

Peña, Botp

RnJvbTogTWlzY2hhIEZpZXJlciBbbWFpbHRvOmYubWlzY2hhQGdtYWlsLmNvbV0gDQojIC4uLmJ1
dCB0aGUgMiBhYm92ZSBpdC4NCg0KY29tcGFyZSwNCg0KDQpDOlxmYW1pbHlccnVieT5ydWJ5IC12
ZSAibGFtYmRhe3x4fCBwdXRzIHg7WzEsMl0uY29sbGVjdHt8eHwgeCsxfTsgcHV0cyB4IH0uY2Fs
bA0KKCdhYWEnKSINCnJ1YnkgMS44LjYgKDIwMDgtMDgtMTEgcGF0Y2hsZXZlbCAyODcpIFtpMzg2
LW1zd2luMzJdDQphYWENCjINCg0KDQpDOlxmYW1pbHlccnVieT5ccnVieTE4N1xiaW5ccnVieSAt
dmUgImxhbWJkYXt8eHwgcHV0cyB4O1sxLDJdLmNvbGxlY3R7fHh8IHgrMX07DQpwdXRzIHggfS5j
YWxsKCdhYWEnKSINCnJ1YnkgMS44LjcgKDIwMDgtMDgtMTEgcGF0Y2hsZXZlbCA3MikgW2kzODYt
bXN3aW4zMl0NCmFhYQ0KMg0KDQoNCkM6XGZhbWlseVxydWJ5PlxydWJ5MS45XGJpblxydWJ5IC12
ZSAibGFtYmRhe3x4fCBwdXRzIHg7WzEsMl0uY29sbGVjdHt8eHwgeCsxfTsNCnB1dHMgeCB9LmNh
bGwoJ2FhYScpIg0KcnVieSAxLjkuMCAoMjAwOC0wNi0yMCByZXZpc2lvbiAxNzQ4MikgW2kzODYt
bXN3aW4zMl0NCi1lOjE6IHdhcm5pbmc6IHNoYWRvd2luZyBvdXRlciBsb2NhbCB2YXJpYWJsZSAt
IHgNCmFhYQ0KYWFhDQoNCg==
 
T

Thomas B.

Mischa said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top