1. Oct 26th, 2005

    Domain specific languages in Ruby

    More Ruby goodness from Jim Weirich, this time a set of slides talking about [domain specific languages](http://onestepback.org/articles/lingo/index.html). And would you believe, Ruby is just a perfect fit for so many use cases. The references at the end will take you to interesting articles about [deferred](http://mephle.org/Criteria/) [expression](http://onestepback.org/index.cgi/Tech/Ruby/SlowingDownCalculations.rdoc) [evaluation](http://nat.truemesh.com/archives/000537.html). I’ve been thinking of using something like Criteria for message selectors, and I wonder how far I can push it. The current iteration of the queue manager allows you to select messages from the queue in one of three ways. With no arguments, it just picks the next message available on the queue (ordered by priority, time of arrival). You can pass a message identifier to retrieve a particular message. Or you can pass selectors to find a message that matches specific criteria based on the message headers. Say you’re sending a message, and expecting a request to that message. You can write something like:

    request_id = queue.put request... do some other stuff ...msg = queue.get :reply_to=>request_id

    But this approach has a limit, you can only select messages when a header matches a specific value. So how do you select all messages with priority 5 or higher, or all messages created in the last hour? Obviously, the Ruby way to do this is to use a block. But since the application and queue manager may be running in different processes, and you can’t send blocks over DRb (or HTTP), that doesn’t work. I’m playing with sending selectors as strings and evaluating them inside the queue manager, but that makes string handling all the more difficult. For example, :reply_to=>request_id becomes “reply == ‘#{request_id}’. Ugly and error prone. Wouldn’t it be wonderful if I can get deferred expression evaluation, so you can write something like:

    msq = queue.get { priority>5 and Time.new.to_i - 3600 }

    and send the expression over to the queue manager for evaluation in a different process?

    Your comment, here ⇓

    Or using OpenID