From: Dave Cantrell Date: 2006-02-08T13:57:55+09:00 Subject: Re: What's the difference between copying and sharing in closure? > Contrast this to Ruby: > > def do_yield() > yield > end > > foo = "FOO" > do_yield() { > foo = "BAR" > } > puts foo # Outputs "BAR". > > Which means you can assign to local variables in the closure's lexical scope > from inside the closure. Question: How is the above different from, say in pseudo code: function do_something(in) foo = in end function foo = "FOO" do_something("BAR") print foo # should still output "BAR", right? Other than the fact that you can create the block logic at call time rather than at declaration time, what is the difference in how the two scopes are handled? In both the Ruby example and the pseudo-code case, the variable foo is a globally-scoped variable (well, for that code snippet anyway) and therefore should be accessible to any function that is subordinate to it. After reading the example above I was led to try something similar. I'm definitely a Ruby Nuby (I had to research the IO routines to pad the code for this e-mail) so I had to fiddle with the variable scoping for a while to get it to work. It wasn't until I managed to get the variable assignment into the right place that I got something other than nil or a proc object. But in the end, writing this helped me better understand the way Ruby shares variables in closures. Though I'm still confused as to how it's truly different from regular scoping rules. class MethodList def initialize @methods = [] end def add(&block) @methods << block end def run(param) i = param @methods.each { |m| i = m.call(i) } i end end m = MethodList.new m.add { |x| x + 1 } m.add { |x| x + 1 } m.add { |x| x + 1 } puts m.run(1) Which, of course, outputs 4. What tripped me up was getting the hang of the proper way to update the i variable and the proper way to output the result. I first tried to have the puts in each of the m.add {} blocks -- then I realized I'm overdue for sleep. Doh. Can you see me getting the hang of blocks? :) Any clarification greatly appreciated. Thanks, -dave