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