On Nov 7, 2007, at 3:04 PM, Adam Anderson wrote:
> I want any method to implicitly check the scope of the class in which
> the method is being called and *THEN* check the scope outside the  
> class.
> This is just an exercise in making code more readable and require less
> typing, as far I am concerned.

I think what you are suggesting is the ability to queue up a number
of objects to be used as 'self' while a block is being evaluated.  If
none of the objects can handle a message, then the process would
be repeated this time looking for method_missing().

Something like:

     also_eval(a,b,c) { #code }

So the code would be executed with the 'normal' self.  If a method
was not found it would be searched for via object a then b then c.

The main problem with implementing this is that you really want to
insert a step between the normal method lookup and method_missing and
I don't think that can be done without using method_missing itself.

Anyway, here is a solution that uses method_missing to link the
objects.  The last object in the chain is responsible for doing
something via its own method_missing.  This solution will not
properly handle nested blocks due the limitations on define_method().
I'm sure this could be improved.  I'm not sure how useful this is
but it was a fun problem to think through.

module Kernel
   def also_eval(*args, &block)
     block_self = eval "self", block.binding
     args.inject(block_self) { |op1, op2|
       (class <<op1; self; end).send(:define_method, :method_missing)  
{ |*args|
         begin
           op2.send(*args)
         rescue NoMethodError
          begin
            super
          rescue NoMethodError
            op2.send(:method_missing, *args)
          end
         end
       }
       op2
     }
     block.call
   end
end

class A
   also_eval({:a=>1}, [100,200]) {
     p self         # A
     p keys         # the hash
     p first        # the array
     p bogus        # not found
   }
end