How to hide your Java with a DSL using JRuby

Last time I showed some Java code for building a simple tree. Then I showed a DSL for representing that tree. The point was basically to make you want to create such a DSL. This time I am going to show you how to make the DSL actually do something. We are going to write all the code that will allow that DSL to build a tree. If you've never seen it, or don't remember, please look back at the code from the last post. It's important to see the java code we started with and the DSL that we are going to implement. It's kind of like those before and after pictures you're always looking at. Seriously, come back when you are done, and this will make more sense.

It's not odd to start with the DSL. In fact I usually start with a language that would be ideal and then modify it just enough so that it is valid Ruby syntax. It is important to understand the language features and know how much you can get away with as far as syntax. As you begin implementing it, your language will probably change. In the end you hopefully end up with a concise and powerful abstraction.

Ruby has a lot of features that make it ideal for internal DSL's. Literal Arrays and Hashes are simple and very useful here, even though we won't use them today. We are going to focus on blocks and method_missing. Note that all of these concepts are missing from Java.

We are going to decorate our Java TreeNode class with JRuby. That's right, we are going to slap behavior implemented in Ruby directly on our Java class. And we are going to make it do things that can't even be done in Java. But first I want to introduce the IRB.

The IRB is a command line that you can execute Ruby in. With JRuby you get a JIRB, which is the same thing except you can execute Java there too. Sweet, interactive Java! As a Java developer, it is worth learning about JRuby just for this new ability. It's a more efficient way to explore how Java classes work than implementing main methods all over the place. I have also prototyped new behavior on my Java objects very effectively through the JIRB. The following examples are what I typed into the JIRB to test my ideas for the implementation of the DSL. If something doesn't work out, you just keep typing. The JIRB lets you try something and see the results very quickly. I have never felt so close to my Java code.


This first piece of new behavior we added to TreeNode is a good example. The new line character is different in Java and Ruby so we switch them out in the toString method. We had to require the jar for this class. Then we assign the qualified class name to a constant for convenience. After that adding a new method to our Java class is done as if it were Ruby. We could call toString, but JRuby allows us to call the Java methods with Ruby style so we call to_string instead. Note that is is completely unnecessary for the DSL. I only did it because I already had a toString that wrote out in the DSL format, and I wanted it to look right in the JIRB. The next example is where the meat is.


This code does most of the work for us. Method_missing is a special method in Ruby. A call to method_missing is what happens if you call a method that doesn't explicitly exist. Java wouldn't even compile if you did something like this. In this case we find or create a TreeNode with the name of the method. This lets us represent a path in our tree like this: shape.ellipse.circle

As opposed to this in Java.


So this is 1 line of our DSL rather than 22 lines of Java. Even if your developers don't know Ruby it should be obvious that they are going to have an easier time writing this immediately.

This path stuff is cool, but it's not what I promised. Since our data structure is a tree, we want to express multiple children for each TreeNode. To do this we are going to use blocks. Blocks are a way to pass executable code into a method. A good example of using a block is the call to the find method in the first line of our method_missing way up there. For each child in the Collection returned by getChildren() on this TreeNode we are checking to see if it has the same name as the method name that invoked method_missing.

Blocks will also allow us to describe a tree structure. The way this works is that method_missing gets called recursively. Each time it will find or create the named TreeNode, and then it allows that TreeNode to evaluate the remaining structure. All methods in Ruby can be passed a block. Blocks are placed after a method call and fit within '{...}' or 'do...end.' I chose the brackets because I liked the way it made the language look, but either would actually work. Nesting the blocks allows for a natural tree structure. The block can be accessed in the method with an extra parameter. In this case &block. Don't get too worried about the '&' just yet, it is the concepts that are important. The second to the last line deals with constructing the children. If a block which represents substructure of the tree is given, it is evaluated on our child. The way that we recursively traverse the described children is the most complicated and important part of the whole thing. Now we can build a tree described like this.


For readability it is nice to leave off the parens on the methods called. Everything that is a word in this DSL is actually a method call that invokes method missing, which creates a TreeNode that is added as a child. There is a bit of a chicken and egg problem with this example though. Once we have a TreeNode we are rolling, but how do we get our hands on the root TreeNode, in this case "shape?" Here is a way to start the whole thing off that is consistent with our DSL.


To make this work we just have to implement Tree to create our first TreeNode, and then hand the rest of the hierarchy off to it.


One of my first Ruby projects was a DSL, and it was not a bad way to learn the language. I have taken these concepts further in production code by describing a complicated meta model with frames and slots, effective dating, and internal rules. The ideas presented here scaled well to the more complicated project. The performance was also acceptable. There are a few problems that I neglected to mention because their solutions are straight forward. One of the more noteworthy is the possibility that you would have to encode and decode the names of TreeNodes into valid method names if they weren't already. This is one of the costs of using an internal DSL. That's fine with me because it is much easier than writing a parser. In the next entry I would like to show how this DSL can be used for more than just building the tree.

21 comments:

Steve Smith said...

Great and Useful Article.

Online Java Training

Online Java Training from India

Online Java Training

Online Java Training From India

Java Training Institutes in Chennai

Java Training in Chennai

Java Interview Questions

Java Tutorials

for IT the said...

Hibernate Online Training Hibernate Online Training Hibernate Training in Chennai Hibernate Training in Chennai Java Online Training Java Online Training

Hibernate Training Institutes in ChennaiHibernate Training Institutes in Chennai Java Online Training Java Online Training Java Online Training Java Online Training

kim john said...

Amazing article! I was confused about Java Training in Chennai , but now got a clear view of the definition. Appreciate your hard work!
Java Course in Chennai
Best Java Training in Chennai

zasi besant said...

Thanks for one marvelous posting! I enjoyed reading it; you are a great author. I will make sure to bookmark your blog and may come back someday. I want to encourage that you continue your great posts, have a nice weekend!


Java Training in Chennai


Java Training in Bangalore


Java Training in Bangalore

Mageshkumar said...

This was very informative for me. Please continue this awesome work. Thank you.
Best Java Training in Chennai

Anu. SSDN said...

Excellent and very cool idea and the subject at the top of magnificence and I am happy to this post. Interesting post! I am very glad to read your informative blog...thanks a lot for your valuable sharing. I was reading through some of your content on this article and I conceive this blog is really instructive! If you are looking for in depth Java certification training delhi

Swathi Samala said...

This is very blog ,and it's very usefull for developers
Java Online Training

Sourav Paul said...

Thanks for your information. such a useful information.

Java training in Bangalore

Dhileepan K said...

Awesome and interesting article. Great things you've always shared with us. Thanks. Just continue composing this kind of post.
Java Training in Chennai | Java Training Institute in Chennai

Dipanwita said...

I loved your blog. Never came across anything so interesting. java training in chennai

Revathy A said...

Thanks a lot for sharing us about this update. Hope you will not get tired on making posts as informative as this. 
angularjs Training in marathahalli

angularjs interview questions and answers

angularjs Training in bangalore

angularjs Training in bangalore

angularjs Training in chennai

automation anywhere online Training

simbu said...

I read this post two times, I like it so much, please try to keep posting & Let me introduce other material that may be good for our community.
Java training in Bangalore | Java training in Btm layout

Java training in Bangalore |Java training in Rajaji nagar

Java training in Bangalore | Java training in Kalyan nagar

thulasi ragini said...

I would like to thank you for the efforts you have made in writing this article. I am hoping the same best work from you in the future as well. In fact your creative writing abilities has inspired me to start my own BlogEngine blog now. Really the blogging is spreading its wings rapidly. Your write up is a fine example of it.
Python training in bangalore
Python course in pune
Python training in bangalore

kevin antony said...

This is most informative and also this post most user friendly and super navigation to all posts... Thank you so much for giving this information to me.

rpa training in chennai
rpa training in bangalore
rpa course in bangalore
best rpa training in bangalore
rpa online training

Ram priya said...

I appreciate your efforts because it conveys the message of what you are trying to say. It's a great skill to make even the person who doesn't know about the subject could able to understand the subject . Your blogs are understandable and also elaborately described. I hope to read more and more interesting articles from your blog. All the best.
Data Science Training in Chennai | Best Data science Training in Chennai
Data Science training in anna nagar | Data science training in Chennai
Data Science training in chennai | Best Data Science training in chennai
Data science training in Bangalore | Data Science training institute in Bangalore
Data Science training in marathahalli | Data Science training in Bangalore
Data Science interview questions and answers

johnsy sai said...

Great Article… I love to read your articles because your writing style is too good, its is very very helpful for all of us and I never get bored while reading your article because, they are becomes a more and more interesting from the starting lines until the end.
Best Devops Training in pune
excel advanced excel training in bangalore
Devops Training in Chennai

vijay antony said...

I am really happy with your blog because your article is very unique and powerful for new reader.
Click here:
selenium training in chennai | selenium course in chennai
selenium training in bangalore | selenium course in bangalore
selenium training in Pune | selenium course in pune | selenium class in pune
selenium training in Pune | selenium course in pune | selenium class in pune
selenium online training | selenium training online | online training on selenium

sandy star said...

Hello! This is my first visit to your blog! We are a team of volunteers and starting a new initiative in a community in the same niche. Your blog provided us useful information to work on. You have done an outstanding job.
Best AWS Training in Chennai | Amazon Web Services Training in Chennai
AWS Training in Bangalore | Amazon Web Services Training in Bangalore
Amazon Web Services Training in Pune | Best AWS Training in Pune

Dharani M said...

Great blog
java training in Marathahalli

spring training in Marathahalli

java training institute in Marathahalli

spring and hibernate training in Marathahalli

Dharani M said...

Nice blog


java training in Marathahalli

spring training in Marathahalli

java training institute in Marathahalli

spring and hibernate training in Marathahalli

mounika said...

Nice post..

DOT NET training in btm

dot net training institute in btm

dot net course in btm

best dot net training institute in btm