Zach Dennis said: > Also with the with block being how Jamis Buck and David A. Black posted > it works nice with methods as well. > > def talk > puts "i'm talking" > end > > def Test > def test > puts "i'm testing" > end > end > > t = Test.new > with t do > talk > test > end > > 'talk' is called correctly because it is in the current scope of the > *with* block and 'test' is called correctly because it exists on object > 't'. The above works, but some very similar code is broken ... For example: class Test def test puts "i'm testing" end end class Dog def talk puts "i'm talking" end def testing_dog talk # Class Dog#talk t = Test.new with t do test # Calls Test#test talk # ERROR: undefined local variable or method `talk' end end end This is because the second call to talk is not evaluated in the lexical scope of the calling object Dog, but within the scope of the Test object. Dog#talk exists, but Test#talk does not. (Your example missed the problem by putting +talk+ into the global scope. There is an awkward work around. First write +with+ like this: module Kernel def with(obj, &block) obj.instance_eval { @self = eval("self", block) } obj.instance_eval &block end end Then reference Dog#talk like this ... class Dog def talk puts "i'm talking" end def testing_dog talk # Class Dog#talk t = Test.new with t do test # Calls Test#test @self.talk # Calls Dog#talk end end end -- -- Jim Weirich jim / weirichhouse.org http://onestepback.org ----------------------------------------------------------------- "Beware of bugs in the above code; I have only proved it correct, not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)