Forum: Ruby Creating a DSL in ruby

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.
F48118fe74b0c7f6fd82a0ee422fa34e?d=identicon&s=25 snacktime (Guest)
on 2007-06-29 06:50
(Received via mailing list)
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
D5846a004fa29b8c5478bedf3dfd75c3?d=identicon&s=25 Adam Bozanich (Guest)
on 2007-06-29 09:10
(Received via mailing list)
On 6/28/07, snacktime <snacktime@gmail.com> wrote:
>
>
> 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?



racc http://i.loveruby.net/en/projects/racc/
83668557add122451315d38b24a9fe62?d=identicon&s=25 Michael Hollins (Guest)
on 2007-06-29 18:15
(Received via mailing list)
snacktime wrote:
>
> 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.
B1b1d33e0655e841d4fd8467359c58d0?d=identicon&s=25 Yossef Mendelssohn (Guest)
on 2007-07-02 15:35
(Received via mailing list)
If I may, you could look into a fluent interface (http://
www.martinfowler.com/bliki/FluentInterface.html) instead of a DSL.  I
make this distinction because "DSL" seems to have become a term
meaning "something with lots of class methods and blocks" because
that's one simple Ruby implementation.

Michael Hollins suggested something like

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


but how about something like


charge(10.dollars).on(date_x).then.charge(20.dollars).every(:month).times(12).starting(date2)

instead?


If that's not enough to turn you on, look at how well it works with
mocking/stubbing in places like RSpec and Mocha (http://
mocha.rubyforge.org/examples/mocha.html).
5d38ab152e1e3e219512a9859fcd93af?d=identicon&s=25 David Chelimsky (Guest)
on 2007-07-02 18:11
(Received via mailing list)
On 7/2/07, Yossef Mendelssohn <ymendel@pobox.com> wrote:
>      repeat 12 do
> 
charge(10.dollars).on(date_x).then.charge(20.dollars).every(:month).times(12).starting(date2)
You can even get more natural language using eval - imagine this
expressed as:

charge 10 dollars on 07/02/2007 then charge 20 dollars every month for
12 months starting on 08/01/2007

Check out Jay Fields' writing on Business Natural Languages:

http://bnl.jayfields.com/01_introduction.html
B1b1d33e0655e841d4fd8467359c58d0?d=identicon&s=25 Yossef Mendelssohn (Guest)
on 2007-07-02 20:35
(Received via mailing list)
On Jul 2, 11:08 am, "David Chelimsky" <dchelim...@gmail.com> wrote:
> You can even get more natural language using eval - imagine this expressed as:
>
> charge 10 dollars on 07/02/2007 then charge 20 dollars every month for
> 12 months starting on 08/01/2007
>
> Check out Jay Fields' writing on Business Natural Languages:
>
> http://bnl.jayfields.com/01_introduction.html

Tricky.  It's like a super-fluent interface hidden behind a parser.
Personally, I have no trouble with all the dots and parens, but I can
definitely appreciate how it would be nicer for domain experts not to
necessarily have to deal with them.
This topic is locked and can not be replied to.