From: Isaac Sanders Date: 2011-11-07T07:47:50+09:00 Subject: Re: Tricky DSL, how to do it? --000e0cd52da633ade704b118babd Content-Type: text/plain; charset=ISO-8859-1 You are missing a `super` on the method_missing. first you should ask if is a method on the class, and if it is, call super with no args. try: class Evaluator < BasicObject def initialize(&block) @__config__ = {} instance_eval(&block) if block end def __config__ @__config__ end def method_missing(sym, *args, &block) respond_to? sym ? super : @__config__[sym] = block end end On Sun, Nov 6, 2011 at 5:35 PM, Intransition wrote > I'd want to write a DSL such that a surface method_missing catches > undefined methods and records the blocks that they define e.g. > > foo do > puts "foo" > end > > So I would end up with: > > { :foo=># } > > Presently I have something like this: > > # > class Evaluator < BasicObject > def initialize(&block) > @__config__ = {} > instance_eval(&block) if block > end > > def __config__ > @__config__ > end > > def method_missing(sym, *args, &block) > @__config__[sym] = block > end > end > > However when I call on a block I want it to evaluate as if in the defining > context (in this case toplevel), not inside the "DSL" class that evaluated > via method_missing. > > e = Evaluator.new do > foo do > puts "foo" > end > end > > e.__config__[:foo].call > > Instead of what I want, I get a method missing error for #puts. > > Any ideas? > -- Sincerely, Isaac Sanders Section C-4B Vice Chief, Order of the Arrow Vice Chief of Administration, Tecumseh #65 Eagle Scout --000e0cd52da633ade704b118babd--