------ art_454_14443894.1320693184523 Content-Type: multipart/alternative; boundary --- art_455_25769159.1320693184523" ------ art_455_25769159.1320693184523 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit On Monday, November 7, 2011 9:14:44 AM UTC-5, Sean O'Halpin wrote: > > You could capture the calling self by getting it from the binding of > the block and hide the evaluating call behind your own #eval method: > > class Evaluator < BasicObject > def initialize(&block) > @__config__ } > if block > @context lock.binding.eval("self") > instance_eval(&block) > end > end > > def __config__ > @__config__ > end > > def method_missing(sym, *args, &block) > @__config__[sym] lock > end > > def eval(sym, *args) > @context.instance_exec(*args, &@__config__[sym]) > end > > end > > e valuator.new do > foo do > puts "foo" > end > > bar do |txt| > puts "txt {txt}" > end > end > > e.eval(:foo) # "foo" > e.eval(:bar, "hello") # "txt ello" > Nicely coded. And spot on. If I didn't know that self would always be toplevel in my particular case this is the code I would be using. Actually... this code seems like it might make for a good general use DSL pattern. I'm going to try to generalize it further and see if makes sense to make it a reusable library. What do you think? ------ art_455_25769159.1320693184523 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <br><br>On Monday, November 7, 2011 9:14:44 AM UTC-5, Sean O'Halpin wrote:<blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><p>You could capture the calling self by getting it from the binding of<br>the block and hide the evaluating call behind your own #eval method:</p><p>class Evaluator < BasicObject<br> def initialize(&block)<br> @__config__ = {}<br> if block<br> @context = block.binding.eval("self")<br> instance_eval(&block)<br> end<br> end</p><p> def __config__<br> @__config__<br> end</p><p> def method_missing(sym, *args, &block)<br> @__config__[sym] = block<br> end</p><p> def eval(sym, *args)<br> @context.instance_exec(*args, &@__config__[sym])<br> end</p><p>end</p><p>e = Evaluator.new do<br> foo do<br> puts "foo"<br> end</p><p> bar do |txt|<br> puts "txt = #{txt}"<br> end<br>end</p><p>e.eval(:foo) # => "foo"<br>e.eval(:bar, "hello") # => "txt = hello"</p></blockquote><div>Nicely coded. And spot on. If I didn't know that self would always beoplevel in my particular case this is the code I would be using. </div><div><br></div><div>Actually... this code seems like it might make for aood general use DSL pattern. I'm going to try to generalize it further and see if makes sense to make it a reusable library. </div><div><br></div><div>What do you think?</div><div><br></div><blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p></blockquote> ------ art_455_25769159.1320693184523-- ------ art_454_14443894.1320693184523--