From: Brian Candler Date: 2009-05-05T19:32:11+09:00 Subject: Re: a DSL + scope problem 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/.