From: "Thomas B." Date: 2008-09-20T02:27:44+09:00 Subject: Re: That was unexpected -- strange scoping behavior Patrick Doyle 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. -- Posted via http://www.ruby-forum.com/.