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