Re: ruby and DSL



On Feb 19, 2008, at 9:30 PM, P Rajmohan Banavi-A17190 wrote:

Are there any ruby book(s) that explains more in detail about
DSL(Domain
Specific Language) implementation in ruby? Any pointers to online
tutorials will also be of help.

I don't know if there are any books that directly address this, but a
good way to learn about DSLs is to pick some apart and figure out what
about the language work for you and how the authors implemented it.
rSpec is a great example because it uses the flexibility of Ruby to
create an expressive language that models its problem domain. So, for
example, you can write:

result.should eql(3)

This reads like English, but it is actually a clever bit of
programming. There is a method called "should" that is mixed into
Object by rSpec. Because everything inherits from Object, all
descendent objects gain the "should" method. Simplifying a bit, the
"should" method calls a matcher called "eql" with the argument 3. If
"eql" returns true, then the spec passes, otherwise the spec fails.
Again, this oversimplifies what's going on, but you can see that by
placing method calls carefully, a very readable language for
expressing specifications has been created.

Another example from the rSpec bag of tricks has to do with
expectations on mock objects:

@cash_machine.should_receive(:withdraw).twice.and_return(true)

This kind of method chaining is very nice in DSLs, but it relies on
you to create a structure in which the expected return value of each
method is an object on which any of the chained methods can be
invoked. So, should_receive must return an object that responds to
twice. twice must return an object that responds to and_return. As it
turns out, you can write:

@cash_machine.should_receive(:withdraw).and_return(false)
@cash_machine.should_receive(:deposit).once.and_return(true)
@cash_machine
should_receive(:balance).once.with_any_args.and_return(150)

So you can see that rSpec expectations are crafted such that you can
really chain an expressive set of constraints on an object that is
being mocked.

Jamis Buck writes in an older blog post (http://weblog.jamisbuck.org/2006/3/9/integration-testing-in-rails-1-1
) about integration testing in Rails. In the process of the post,
Jamis extracts a DSL out of the testing scenario so that it becomes
quite natural to use.

Of course, Rails is a huge example of DSLs. I don't consider Rails one
DSL, but several. Obviously, ActiveRecord is an implementation of a
pattern, but where the DSL part comes into play is in how
relationships and validations and such are handled:

class CashMachine < ActiveRecord::Base
has_many :customers
belongs_to :bank
validates_presence_of :security_camera
# ...
end

Well, you can see I'm not in the banking business, but no matter. The
point is that even the casual reader could see that any given cash
machine has many (zero or more) customers and that that machine
belongs uniquely to a bank. Further, a valid cash machine has to have
a security camera. It's totally readable (unlike my typical cryptic
one-liners with a couple of regex'es thrown in). The trick is to
evolve a language that is possible to speak.

Creating a DSL has to do with having a problem domain and factoring
out common operations within that domain. While it's possible to write
about a very real DSL such as rSpec, or an almost-real one like Jamis'
integration testing scenario, it's not possible to give you a manual
and say "here's how to write your very own DSL."

I hope this is useful info.

.



Relevant Pages

  • Re: Joel Spolsky on languages for web programming
    ... defining a domain-specific language in Ruby - cf. Og data definition, ... beast to a DSL in the sense that I've come across the term in Ruby. ... Rails and rake are internal DSLs, and Ruby makes internal DSL creation ...
    (comp.lang.ruby)
  • implementing a domain specific language - fit and expectations
    ... i used to work on team that wrote flight scheduling optimization ... optimization problem in our setting. ... a domain specific language fits nicely. ... and the dsl could let them play with different attempts at solving the ...
    (comp.lang.scheme)
  • Re: book
    ... Rails contains several very good examples of DSLs invented _within_ the base ... (If your base language can't do that, ... The goal of a DSL is you can read that statement, from left to right, and it ... Rails training from David A. Black and Ruby Power and Light: ...
    (comp.lang.ruby)
  • Re: static class inheritance, generalized
    ... Jon Skeet [C# MVP] wrote: ... any math method likely will be in Math, ... In a procedural language, one wouldn't use 'Copy'. ... That same DSL ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: LISP diploma project idea
    ... rather than solving problems in general-purpose programming languages, ... The paper offers nothing higher level than a "Collection DSL". ... The man knows nothing of Lisp. ... to the language, it becomes increasingly difficult to add ...
    (comp.lang.lisp)