On Oct 6, 2008, at 9:56 AM, Paul Brannan wrote: > Instance_eval for initialization has surprising behavior for instance > variables (e.g. as in Ruby/Tk). > > A method that affects only method calls and not instance variables > would > make this idiom more viable. > > I don't know whether that is a good thing or a bad thing. Here's an thread-safe, pure Ruby version of with: -- Start Code ---------------------------------------- if RUBY_VERSION < "1.9" require 'builder/blankslate' BasicObject = BlankSlate end class MethodDirector < BasicObject def initialize(objs) @objects = objs end def method_missing(sym, *args, &block) @objects.each do |obj| begin return obj.send(sym, *args, &block) rescue ::NoMethodError => ex # Try the next one end end super end end def with(obj, &block) containing_obj = eval("self", block.binding) director = MethodDirector.new([obj, containing_obj]) director.instance_eval(&block) end -- End Code ---------------------------------------- The above code has the quirk that within the block, "self" is neither the containing object, nor the object given to with, but the MethodDirector object. The performance characteristics of this implementation are propably pretty poor. Not only do we create a new MethodDirector object each time, but we rely on method_missing to catch all method calls with an implicit object. I considered using something like this for Builder at one point in time and rejected it because of the complexity/magic. I still think that was a good decision. -- -- Jim Weirich -- jim.weirich / gmail.com