From: Intransition Date: 2011-11-08T05:56:26+09:00 Subject: Re: Tricky DSL, how to do it? ------=_Part_12_22768450.1320699383619 Content-Type: multipart/alternative; boundary="----=_Part_13_14599951.1320699383619" ------=_Part_13_14599951.1320699383619 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Check it out: class ContextDSL < BasicObject def initialize(&block) @missing_block = block end def eval!(&block) @context = block.binding.eval("self") instance_eval(&block) end def method_missing(sym, *xargs, &block) context = @context context_block = ::Proc.new do |*args| context.instance_exec(*args, &block) end @missing_block.call(sym, context_block) end end Try it out: config = {} dsl = ContextDSL.new do |name, block| config[name] = block end dsl.eval! do foo do puts self end end config[:foo].call #=>
Now with this general solution in hand, it's really got me asking why Ruby just doesn't provide a way to set the context, e.g. f = lambda{ self } f.context = "Any Object" f.call #=> "Any Object" ------=_Part_13_14599951.1320699383619 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Check it out:

  class ContextDSL < Ba= sicObject

    def initialize(&block)=
      @missing_block =3D block
  &= nbsp; end

    def eval!(&block)
      @context =3D block.binding.eval("self")
      instance_eval(&block)
    en= d

    def method_missing(sym, *xargs, &a= mp;block)
      context =3D @context
&nb= sp;     context_block =3D ::Proc.new do |*args|
  =       context.instance_exec(*args, &block)
&nb= sp;     end
      @missing_block.call(sy= m, context_block)
    end

&nbs= p; end

Try it out:

 = config =3D {}

  dsl =3D ContextDSL.new do |n= ame, block|
    config[name] =3D block
 = end

  dsl.eval! do
    f= oo do
      puts self
    end<= /div>
  end

  config[:foo].call &nbs= p;#=3D> <main>

Now with this general solu= tion in hand, it's really got me asking why Ruby just doesn't provide a way= to set the context, e.g.

  f =3D lambda{ sel= f }

  f.context =3D "Any Object"
  f.call  #=3D> "Any Object"

------=_Part_13_14599951.1320699383619-- ------=_Part_12_22768450.1320699383619--