From: Yuh-Ruey Chen Date: 2008-11-01T06:08:59+09:00 Subject: Re: How to access to local variables in enclosing scopes? On Oct 31, 3:19 pm, Mike Gold wrote: > Yuh-Ruey Chen wrote: > > This is not what I'm really looking for. I don't care about accessing > > variables within another unrelated scope - in fact, unless explicitly > > allowed, it should not be allowed. I only care about accessing > > variables in enclosing scopes. > > Just to verify we are on the same page: define_method solves all your > problems, right?  If you don't wish to use Ruby 1.9 (which will be > officially released in two months) then the corner case is default > arguments, which can be done via the example I gave. I was not aware that this was being fixed. Thanks for the tip. I've also noticed that there is a break in symmetry between |def| and | define_method| besides this block issue. Compare: x = 0 C.define_method(:foo) do puts x # refers to outside x puts self.x # refers and calls this object's method x end with: x = 0 C.module_eval do def foo # no way to refer to outside x, but something like |scope.x| would be nice for symmetry puts x # refers and calls this object's method x end end These would be functionally equivalent if there were some way, analagous to the former's |self.x|, to access vars in enclosing scopes. I'd argue that such a symmetry would be elegant. > Keep in mind that you are looking at just one side of the coin.  There's > a flip side to it.  Preventing local variables from willy-nilly > infecting your methods is a Good Thing, and is usually what you want. I agree, it's a good thing. x = 10 def foo x # accessed outside x end wouldn't be a good thing, because adding a new method called "x" would ruin it. But something like: x = 10 def foo scope.x end would not be as fragile, assuming |scope| is a new builtin method that does what you'd expect it do. > If you really want x to be globally accessible then you should do > > require 'ostruct' > GLOBALS = OpenStruct.new > GLOBALS.x = 10 > > def foo >   GLOBALS.x > end > > class Klass >   GLOBALS.x >   def bar >     GLOBALS.x >   end > end > > This makes your intention explicit.  If you know python, you've probably > heard the phrase, "Explicit is better than implicit."  :) Except I do NOT want x to be globally accessible. I just want to to be accessible be child scopes. If I wanted it to be globally accessible, then I would just use global variables.