From: "David A. Black" Date: 2004-08-26T06:56:13+09:00 Subject: Re: *with* block? Hi -- On Wed, 25 Aug 2004, Jim Weirich wrote: > 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 You could also do: def testing_dog s = self t = Test.new talk with t do test s.talk end end (i.e., put the burden of providing a reference to self-the-Dog to on the method, rather than on 'with') David -- David A. Black dblack@wobblini.net