From: Brian Candler Date: 2010-10-21T17:32:27+09:00 Subject: Re: scope when reopening method Rahul Kumar wrote in post #956000: > class My > > # str contains some value generated by My > def meth str > end > > def call_meth > meth "abc" > end > end > > > # ------ my application starts here > > arr = [] > > m = My.new > def m.meth(str) > # access some other object in application scope > arr << str > do_something str # call some method in my app > end > > I have the method "meth" above which is of interest to user apps. > The app overrides the method and would like to access methods or > variables > in my application scope. By "My application scope", you mean the top-level scope? For example, you want methods inside instances of My to be able to access local variables like 'arr' ? The simple answer(*) is that you can't - each 'def' method and 'class' definition starts its own local variable scope. That's why they're called "local" variables :-) You should pass references to those objects explicitly when needed. For example: class My def initialize(arr) @arr = arr end def meth(str) @arr << str do_something str end end Because everything in Ruby is an object reference, you are only copying the reference, not copying the entire object. So @arr << str modifies the same array that arr << str did before. Or you could just pass the object reference only when needed: def meth(str, arr) arr << str do_something str end It depends on the cleanest way to encapsulate the logic you're implementing. > Is there anyway this is possible (other than using global variables) ? > To me it appears that meth() can only access what is in that objects > scope plus globals. thx. Not exactly: meth() can only access local variables in that *method's* scope, plus instance variables of the object (@foo), plus global variables ($bar) Generally you want to avoid global variables at all costs. At worst, you can use an instance variable of the class object (since the class itself is an object) class Foo def self.bar=(x) @bar=x end def self.bar @bar end end Foo.bar = 123 puts Foo.bar This is like a global variable, but at least it's qualified by class 'Foo' so you know you're not stamping on any other global variable. Regards, Brian. (*) The long answer is you can break this rule using eval and binding, e.g. TOPLEVEL_BINDING, but you really don't want to do that. -- Posted via http://www.ruby-forum.com/.