Forum: Ruby creating a DSL: adding random methods

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
dc (Guest)
on 2008-12-07 17:05
(Received via mailing list)
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
Tom L. (Guest)
on 2008-12-07 18:15
(Received via mailing list)
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
Shawn A. (Guest)
on 2008-12-07 19:33
(Received via mailing list)
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
David A. Black (Guest)
on 2008-12-07 19:57
(Received via mailing list)
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
This topic is locked and can not be replied to.