# A DSL + scope problem

**URL:** <https://www.ruby-forum.com/t/a-dsl-scope-problem/167191>\
**Category:** Ruby\
**Created:** [May 5, 2009, 9:24am UTC](https://www.ruby-forum.com/t/a-dsl-scope-problem/167191 "2009-05-05T09:24:20Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Srijayanth\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e95f7d/32.png) [@Srijayanth\_S](https://www.ruby-forum.com/u/Srijayanth_S)\
**Post date:** [May 5, 2009, 9:24am UTC](https://www.ruby-forum.com/t/a-dsl-scope-problem/167191/1 "2009-05-05T09:24:20Z")

</div>

Hello,

Wrt:

[http://groups.google.com/group/comp.lang.ruby/browse\_thread/thread/689cbe271d680979/5ba5a52ba929b142?lnk=raot&fwc=2&pli=1](http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/689cbe271d680979/5ba5a52ba929b142?lnk=raot&fwc=2&pli=1)

Basically I have a log file where different lines need to be mapped to  
different statements, for instance:

“Look a shiny red Ferrari!” → “Italian metal”

However, it is not a simple mapping alone, there also needs to be some  
intelligence and a state needs to be kept in order to determine some  
other  
fancy stuff. Anyway, the point is, I had an ugly design involving  
abstract  
classes and so on, I’ve gone on to making a DSL where a person can do  
the  
following:

# rule name is fairly pointless, just used to trigger the method\_missing

call 🙂  
rule\_name /regEx/ do |line|

# process the line, apply logic

# Return a mapped new string

end

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…

Thank you,

Jayanth

---

<div class="post-metadata">

**Author:** ![Srijayanth\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e95f7d/32.png) [@Srijayanth\_S](https://www.ruby-forum.com/u/Srijayanth_S)\
**Post date:** [May 5, 2009, 12:32pm UTC](https://www.ruby-forum.com/t/a-dsl-scope-problem/167191/2 "2009-05-05T12:32:08Z")

</div>

Srijayanth S. 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!” }  
=\> #Proc:0xb7ccbed0@:5(irb)  
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.

---

<div class="post-metadata">

**Author:** ![Srijayanth\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e95f7d/32.png) [@Srijayanth\_S](https://www.ruby-forum.com/u/Srijayanth_S)\
**Post date:** [May 6, 2009, 6:49am UTC](https://www.ruby-forum.com/t/a-dsl-scope-problem/167191/3 "2009-05-06T06:49:45Z")

</div>

Thanks Brian,

All of these help. Eventually I would like those using the DSL to define  
their own helper methods.

Jayanth

---

<div class="post-metadata">

**Author:** ![Srijayanth\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e95f7d/32.png) [@Srijayanth\_S](https://www.ruby-forum.com/u/Srijayanth_S)\
**Post date:** [May 6, 2009, 12:54pm UTC](https://www.ruby-forum.com/t/a-dsl-scope-problem/167191/4 "2009-05-06T12:54:49Z")

</div>

I was thinking something of this sort:

class MyDsl  
def load\_helper\_methods filename  
MyDsl.class\_eval(File.read(filename))  
end  
end

and the DSL itself would contain two parts really, one file where the  
helper  
methods are defined, and another for the actual DSL.

Basically:

$ cat foo.dsl  
load\_helper\_methods “my\_helpers”

# the rest of the DSL

# follows

etc

Now, for some annoying reason my head swims with yet other possibilities  
such as making the helper methods a Module and have it be included in  
the  
class etc. Kid in a candy store and all that. Too many options.

Jayanth

---

<div class="post-metadata">

**Author:** ![Srijayanth\_S](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e95f7d/32.png) [@Srijayanth\_S](https://www.ruby-forum.com/u/Srijayanth_S)\
**Post date:** [May 6, 2009, 9:13am UTC](https://www.ruby-forum.com/t/a-dsl-scope-problem/167191/5 "2009-05-06T09:13:40Z")

</div>

On Wed, May 6, 2009 at 6:49 AM, Srijayanth S.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Thanks Brian,
> 
> All of these help. Eventually I would like those using the DSL to define  
> their own helper methods.

… which have scope of?  
Robert
