From: Srijayanth Sridhar Date: 2009-05-06T13:49:20+09:00 Subject: Re: a DSL + scope problem --001e680f102024c62f0469371e25 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Thanks Brian, All of these help. Eventually I would like those using the DSL to define their own helper methods. Jayanth On Tue, May 5, 2009 at 4:02 PM, Brian Candler wrote: > Srijayanth Sridhar wrote: > > Basically what the DSL lets them do is define rules and associated > > blocks on > > certain regexes which all gets put into a table. This has simplified > > things > > a lot, and all they do is create rules. Its all working fine, but now I > > want > > to add another feature. I want to define some common methods in the DSL > > class(like formatting strings a certain way etc), but I want this to be > > available to the people who define the rules and the blocks and use the > > DSL. > > Ideally this is easily accomplished by passing self into the blocks. But > > I > > don't want to burden these chaps with what self is and so on, and > > generally > > speaking passing self seems a little ugly. Is there any other method you > > guys can suggest? > > > > The DSL is being instance_eval-ed... > > If you are doing obj.instance_eval { ... } then 'self' is already obj. > > If these helper methods are pre-defined ones, then just define them > within obj's class. The user should be able to call them. If not, > provide a cut-down example which demonstrates the problem. > > If you want the user to be able to define their own helper methods > within the DSL, this is also possible. You may find "define_method" > helpful, which can define a method within a class, given a block. > > irb(main):002:0> def helper(name, &blk) > irb(main):003:1> (class << self; self; end).class_eval { > define_method(name,&blk) } > irb(main):004:1> end > => nil > irb(main):005:0> helper(:test) { puts "hello!" } > => # > irb(main):006:0> test() > hello! > => nil > > Also, note that class_eval also sets the context for a regular "def". So > if the object you are instance_eval'ing within is actually a module or a > class, and you use class_eval instead, users can just stick 'def' > statements in the DSL to define methods within that class. > > irb(main):001:0> class Foo; end > => nil > irb(main):002:0> Foo.class_eval %{def test; puts "hi"; end} > => nil > irb(main):003:0> Foo.new.test > hi > => nil > > But if you are instance_eval'ing within an instance of Foo, then you > want to define methods within the singleton class of that instance, > which I think is best done using define_method as shown first. > -- > Posted via http://www.ruby-forum.com/. > > --001e680f102024c62f0469371e25--