From: Brian Candler Date: 2008-11-01T20:55:41+09:00 Subject: Re: How to access to local variables in enclosing scopes? There is a another reason why class and def create fresh scopes, related to the way Ruby resolves method / local variable ambiguity. One of the benefits of Ruby is its lack of verbosity: in particular no need to declare variables before using them, and no need to put '()' after a method call if it doesn't have any arguments. The result is compact and readable code. However it leaves an ambiguity: is a bareword like "x" to be interpreted as a method call, i.e. self.x(), or as referring to a local variable? This is resolved statically at parse time with a simple rule. If an assignment expression "x = ..." has been seen earlier in the current scope (regardless of whether it is actually executed), then a bareword "x" is a local variable, otherwise it's a method call. So: def x "hello" end def foo if false x = "bye" end puts x # prints nil (local variable, no value assigned) end This is unusual, but once you've used it, it makes perfect sense. Now consider what would happen if 'def' didn't start a new scope. x = 123 .... 1000 lines of code def x "hello" end def foo puts x # 123 instead of hello? end The code would behave differently, because of the binding to the 'x' outside. For me, the important thing is this: within the method body of 'foo', I can tell for sure whether x is a local variable or a method call, by inspecting *only* the code within that method. If it weren't for this flushing of the scope, then I couldn't be sure without reading the *whole* of the rest of the source file up to that point. The same argument applies to a class, and class methods: # silly example memoize = 99 ... 1000 lines ... class Foo extend Flurble memoize end Just by inspecting the body between 'class Foo' and 'end', I can be sure that memoize must be a method call - perhaps something in module Flurble, or else some method already added to class Class. Without this scope flushing, I would have to scan the whole of the rest of the source file. This behaviour may not sit comfortably with users of certain other programming languages. I say that's fine. Ruby is a different language, and has different idioms. If you are more comfortable with Lisp or Haskell, then use those instead. There are of course pros and cons to each way of doing things, but if you open your mind to new ways of working, you may find the pros are surprisingly substantial. (And I'm sure the same is true when moving in the opposite direction too :-) -- Posted via http://www.ruby-forum.com/.