I happen to be a strong believer in DSLs, in fact, unless for the most computational intensive stuff, I would do everything as a DSL.

In my current setup (research in bioinformatics), I can essentially choose the tools I want. My only constraint is having decent bioinformatics and graphics libraries (ah… and I try to do everything inside a JVM). The constraint excludes Prolog and OCAML, so, based on previous experience, I was working with the pair Python/Jython. Guido explicitly stated that Python 3000 is not going the DSL way. Its his option, I am all for having different approaches to programming, but that is not my option.

Enter Ruby: enough bioinformatics libraries (well, from JRuby one can use JFreeChart and BioJava and, of course, BioRuby) and DSL support.

As my Hello World application I decided to immediately use Ruby’s DSL features, so my first application was a Web Template language (yes, yet another), which I describe here:

Fundamental concepts

  • template – A template for a certain type of page: A title page template, a multicolumn page template, …
  • snippet – A part of a page: A navigation bar, an embedded RSS feed, …
  • page – a certain page: The entry page of my website, the page about bioinformatics. Pages are template based and can use snippets.

The fundamental idea is that, for each template there is a template language tailored for that template, for instance, my entry page looks something like this:

title "Tiago's virtual house"
abstract "Bioinformatics, software development, sports (doing, not watching), cinema, music, ..."
topic ("Bioinformatics") {
  summary "Here you will find software for life sciences"
  subtopic "Soft4Life" {|f| in_link f, "soft4life"}
  subtopic "Molecular adaptation"
  subtopic "Tropical diseases"
}
topic ("another") ...

Different kinds of pages (i.e., with different templates) will have different languages

Interesting Ruby features

  1. instance_eval – instance_eval seems to be the workhorse behind Ruby’s DSLish style. Mainly instance eval takes a string and executes it making the name scope of object visible without having to explicitly refer it, that is, imagine that you have an object myCar of class Vehicle, which has a method called start. In that script you can do just start and not myCar.start. That (coupled with less parenthesis clutter) makes the thing work.
  2. attr_reader and friends – attr_reader is an expedient way of having a getter/setter pattern, nice to spare keystrokes. The annotation/decoration that seems to go with this sure deserves research…
  3. Method catching – I am using method_missing to (naively) convert any non existing method name of a template class to an HTML element, so if one calls object.a it will render <a>…</a> (if one does object.shaite, yes, it will do <shaite>…</shaite> ;) )

“Problems” with Ruby (ie, showing that I am a complete newbie)

I did not like the following things:

  1. yield inside instance_eval (show stopper?) – When yielding inside instance_eval, the “inside object” scope seems to be lost. I.e:
      def sillyMethod()
      end
     
      def goneYielding()
        yield
      end

    The code called on yield will not get sillyMethod (and all others from the of the object yielding) on its scope.
    For me this is the biggest hurdle, can be a show stopper, I will research more here before continuing with Ruby…

  2. Parenthesis – Like this:
    topic ("Bioinformatics") {

    Are those parenthesis really needed (before the code block)? Ruby is quite nice in not needing parenthesis, but in this case I could not get rid of them and I don’t see why… (Actually, I see, its probably just my ignorance for now).

  3. Lots of Rubyisms still lying around – Like this:
    subtopic "Soft4Life" {|f| in_link f, "soft4life"}

    I don’t like to have to write |f|…, as it seems to force things to be too Rubyish (pun really unintended). Intuitively I would say that there is something about variable visibility inside code blocks that does not lend itself to easily to this.
    Also, I would like to do some code rewriting, like just putting in_link “soft4life” and then automatically rewrite it to be something like |f| in_link “soft4life”, f. I would bet that this is possible (again, newbie ignorance). This is not the best example of code rewriting, but I hope the point is clear…

  4. Yielding to multiple code blocks – I would like to yield to multiple code blocks. Seems ridiculous? I could do that in Prolog, and I can think of an example use case: When writing an HTML element, yield to a (first) code block to write the attributes, then yield to a second one to write the content.

Preliminary conclusions

I am still too green Ruby to make a decision (only this piece of code), but it looks good. I suppose most issues are due to my total inexperience with Ruby.

There are a lot of things that still need to be checked (like operators – can one change the semantics? And the precedence (a la Prolog)? And the association (Prolog again)? )…

Resources that I used (and recommend):

Programming Ruby

Ruby Standard Library Documentation

Jay Fields blog, especially this post.

Ola Bini blog, I am reading this metaprogramming post, from time to time, and my next explorations will be around what Ola talks on that post…

I am redesigning my site around this code.The source code will be available if somebody declares some interest…
This is my first Ruby program ever, three days work, please be tolerant with the newbie kind of comments that you surely have read…

PS – Just recently discovered, to be read in the future Creating DSLs in Ruby. I will return to this topic somewhere in the future.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • connotea
  • DZone
  • Reddit
  • Slashdot
  • StumbleUpon
  • Technorati

2 Comments to "Ruby: Hello World"

Please share your thoughts