On Oct 25, 2006, at 2:54 PM, dblack / wobblini.net wrote:

> It's easy, but it can also be a bit obfuscating.  For example:
>
>   class C
>     def initialize(thing)
>       @thing = thing
>     end
>
>     def tell(&block)
>       instance_eval(&block)
>     end
>   end
>
>   c = C.new("Hi")
>
>   @thing = "Hello"
>   c.tell do
>     puts @thing        # Hi
>   end
>
> So you get some perhaps unwanted variable-shadowing, and similarly
> with method calls.

Greg Brown and I were playing around with a solution for the method  
call issue at RubyConf.  Here's the code we came up with:

class C
   def initialize(thing)
     @thing = thing
   end

   attr_reader :thing

   def tell(&block)
     if block and block.arity == 1
       block[self]
     else
       instance_eval(&block)
     end
   end
end

def thing; "Hello" end

c = C.new("Hi")

c.tell do
   thing       # => "Hi"
end

c.tell do |obj|
   thing       # => "Hello"
   obj.thing   # => "Hi"
end

I know people frown on the instance_eval() trick, but this seems to  
be less of a problem.  You can just choose to use the variable when  
you need it.

Just a thought.

James Edward Gray II