On Oct 6, 2008, at 5:11 PM, Jim Weirich wrote:

>
> 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.

I've wished Builder would go to something like the following in the  
past, just to give me more choices when using it:

http://blog.grayproductions.net/articles/dsl_block_styles

I realize we're discussing more clever strategies here though.

James Edward Gray II