Creating a DSL: adding random methods

hi -

I’m trying to create a simple DSL, using method missing.

i want to be able to add different event logic for different
instances, defined in their own files.
trivial example:

eg in fred.rb

event :say do
“hi this is fred!”
end

and joe.rb

event :say do
“joe doesnt say much”
end

so i have a class to implement/create the DSL methods:

def event evt, &block
puts “event: #{evt} , #{event}”
str = "
def #{evt}
#{block}
end
"
puts str
self.class.class_eval(str)
end

after loading the individual fred.rb file in
class Brain
def self.load(filename)
dsl = new
dsl.instance_eval(File.read(filename))
end

then when the event XX do is encountered, i am getting:

ArgumentError: ./parser.rb:37:in ‘event’: wrong number of arguments (0
for 1)

this is the method call

event :say do
puts “.code here…”
end

calling this

def event evt, &block

i was expecting “say” to be passed as the evt (method name) and block
to be the code block after do.
perhaps i need to yield something back to the caller?

appreciate any tips on this!

/dc

Basically, I only wanted to say that your subject line sounded very
promising.

def event evt, &block
puts “event: #{evt} , #{event}”

What does this #{event} refer to?

Regards,
Thomas

Based on what I’m seeing here, it looks as though you may want something
like the publisher library.

http://atomicobjectrb.rubyforge.org/publisher/

Not quite sure how to answer your question though. HTH
/Shawn

Hi –

On Sun, 7 Dec 2008, dc wrote:

“hi this is fred!”
def event evt, &block
puts “event: #{evt} , #{event}”

Right there is where you seem to be calling event without an argument
(inside the string interpolation). I suspect that’s where you’re
getting the “Wrong number of arguments” error.

after loading the individual fred.rb file in

to be the code block after do.
perhaps i need to yield something back to the caller?

appreciate any tips on this!

You can’t use a string representation of a block as code. Instead,
you’d want to do something like this:

def event(evt, &block)
(class << self; self; end).class_eval do
define_method(evt, &block)
end
end

so that you can get the local variable evt and the block into the
method definition. (This isn’t a complete example but it might point
you in a useful direction.)

David