snacktime wrote:
> I'm getting back to a project I've wanted to do for a while now, which
> is to create a DSL for recurring payments.  Something like the
> following:
> 
> Charge $10 on date X then $20 every month for 12 months starting on date Y.
> 
> or
> 
> Charge $10 prorated to end of this month then charge $10 every month
> on the first day starting next month for 5 years.
> 
> I'm thinking I'm better off taking the time to learn a real parser and
> handle it that way.  I have a feeling it would be easier to debug a
> dsl created with a parser then one using regular expressions.
> 
> Any suggestions?
> 
> Chris
> 

I spent the last day developing a DSL in ruby, so it's fairly fresh in my mind. Off the top of my 
head, you could represent your above statement in ruby as something like:

   charge 10.dollars do
     on "10 July 2007"
     repeat 12 do
       charge 20.dollars
       every :month
       starting "30 July 2007"
     end
   end

or perhaps:

   charge 10.dollars, "10 July 2007"
   charge 20.dollars, "30 July 2007" do
     repeat 12
     every :month
   end

or maybe just:

   charge 10.dollars, "10 July 2007"
   charge 20.dollars, "30 July 2007", :repeat => 12, :every => :month

No need for regular expressions in any of the above.

There are a number of ways you could represent money. I've picked one possible approach above. Be 
wary of using floats for money, due to rounding problems. To represent fractional amounts, you could 
use "10.32".dollars if you don't consider that to be too ugly.

For manipulating dates you might want to check out the ActiveSupport gem.

As far as choosing between using ruby and using a parser generator I'd say it comes down to 
analysing your user base. If your users are all programmers, then the ruby approach is an extremely 
productive and powerful way to develop a DSL. In the space of a day or two, you can develop a DSL 
which allows people to specify concepts such as you described, but also end up with a DSL that has 
all the power of ruby and its libraries.

If your users are not programmers, then I'd imagine that they'd struggle with using the DSL, since 
exposure to "all the power of ruby" is likely to cause them pain. For example, if they do something 
wrong (e.g. forget a comma), they'll end up with cryptic messages from the ruby interpreter. That's 
something a programmer has no problems handling, but I'd imagine your non-programmer users would be 
cursing your decision.

cheers,
mick

PS: The DSL I'm developing is to help me with project planning. It includes entities such as 
requirements, tasks, groups of entities, dependencies between entities, etc. For example, you can say:

     group "group-key", "Group Description" , :target_version => "1.0" do
       group "sub-group-key", "Sub Group Description" do
         requirement "1", "Summary of Requirement 1"
         requirement "2", "Summary of Requirement 2"
         requirement "3", "Summary of Requirement 3", :target_version => "2.0"
       end
     end

For inspiration I looked at how Markaby (which BTW is very cool) is implemented.