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)