In Ruby, the equivalent code seems to fail, with local variables not being
accessible in nested methods. For example:
irb(main):018:0> def go
irb(main):019:1> 1.upto(10) do |num|
irb(main):020:2* def my_meth
irb(main):021:3> puts "Printing #{num}"
irb(main):022:3> end
irb(main):023:2> end
irb(main):024:1> end
nil
irb(main):025:0> go
1
irb(main):026:0> my_meth
NameError: undefined local variable or method `num' for
#<Object:0x2b992c8>
from (irb):21:in `my_meth'
from (irb):26
from ?:0
Yep, 'def' always starts a new scope, and no local variables are available
outside:
x = 1
def hello
puts x
end
hello # NameError: undefined local variable or method `x'
I don't think there's any *fundamental* reason why it couldn't happen,
because you can get the effect if you try hard enough:
x = 1
p = proc { puts x }
class <<self; self; end.instance_eval { define_method
hello, p) }
hello #>> 1
x = 4
hello #>> 4
However it would make the scoping rules pretty nasty. Suppose I defined a
local variable using 'x=1' outside of a method, e.g.
class Foo
x = 1
def bar
...
obj.each do |x| # << binds to the same 'x'!!
...
end
end
end
Every single method I defined from that point onwards which referred to 'x'
would bind to the *same* x instead of having its own local 'x'. Even
multiple instances of the class would share the same variable! x would
become like @@x.
At least when 'def' starts a fresh scope, then you don't have to worry about
your local variables being polluted from outside.
Also, the method/local variable ambiguity would become a problem: it would
be impossible to invoke a method called 'x' in the above example either,
because you would be referring to the local variable instead.
Cheers,
Brian.