Thoughts on Rails
Posted on February 14th, 2007 in Programming, Rails | No Comments »

So lately, I have been stretching my legs in a “new” framework – Ruby on Rails. While it is not so new in Internet terms, it’s still maturing and slowly gaining new users. I may not be contributing anything particularly new with this blog entry, but I needed a place to organize my thoughts on the subject.
Rails Philosophy
So, the primary Rails philosophy is “Convention over Configuration”. This is the biggest selling point for any domain-specific application framework, to me – how much boiler-plate do I have to write before I can start mucking with actual logic? Some of the nicest parts of Rails are the things that it Just Does out of the box. Database access and abstraction, file structure organization, standards for separation of concerns and unit tests – all of these normal tasks that affect every web application are taken care of for you ahead of time. That is a remarkably powerful tool.
Of course, this alone is nothing unique or original with Rails. One of the things I liked the most about the Fusebox framework for ColdFusion was that it provides several of these abstractions out of the box. Now, Fusebox isn’t nearly as complex of a framework as Rails – it doesn’t begin to approach things like ORM, pluggable modules, AJAX support, etc. Even its handling of templates is pretty rudimentary by comparison. But it does have “opinions” about software development, and those made it a joy to architect in versus something like raw ColdFusion, PHP, or ASP.
A Java Interlude
Compare this with “Hello World” in J2EE. Look at the steps involved for a “typical distributed J2EE application”:
- Create the EJB project and the HelloWorldEntity container-managed entity bean (CMP)
- Create the EJB to RDB mapping using Cloudscape for the HelloWorldEntity CMP
- Create a HelloWorldSession stateless session bean
- Generate WebSphere deployed code
- Create a server project
- Binding the datasource to the HelloWorldEntity CMP
- Create a data source and Cloudscape database tables
- Creating a Java application client project and implementation
- Create the Web project and a simple Java bean to read and write properties
- Create the HelloWorldServlet servlet
- Create the HTML home page
- Create the JSP for final presentation to the user
- Create a reference to the EJB session bean
- Run the full application on the server
Does this really provide so much more than Rails and its ilk to be worth it? I’m not seeing it.
While J2EE certainly has some conventions, they are at a very low level of abstraction. This may provide flexibility for producing any sort of application you want. But at the same time, that much time spent writing boiler-plate in every app has to be a pain. I will admit that I am no expert in J2EE (I’ve never written anything serious in it), so if this is an unfair characterization, let me know. But it seems to me that any J2EE web application would take at least twice as long to write as a simple scripting language like PHP, and probably an order of magnitude longer to write than something in Rails or Django. Even with static typing, code generators, and IntelliJ, there seems that so much complexity can only complicate matters and ultimately introduce errors (or bad practices) in all but the most careful teams.
But enough dumping on Java. The truth is, as a language, I like it better than a lot of others. And I have a lot of respect for Guy Steele when he writes:
“And you’re right: we were not out to win over the Lisp programmers;
we were after the C++ programmers. We managed to drag a lot of them about halfway to Lisp. Aren’t you happy?”
But at least from afar, the whole Java web application world seems ridiculous.
Back to Rails
Another thing I like about Rails is the Ruby language itself. It definitely has the feel of a Smalltalk-Lisp-Perl hybrid – with its emphasis on “everything-is-an-object” and blocks, combined with a seat-of-your-pants, “static typing? what’s that?” scripting language feel. Look at some of these little snippets:
Using ActiveSupport’s Symbol#to_proc:
[1, 2, 3].map(&:to_s) #=> ["1", "2", "3"]
Array shuffling:
class Array def shuffle n = [] while !empty? n < < delete_at(rand(size)) end n end end # Usage [1,2,3,4,5].shuffle #=> [2, 4, 5, 1, 3]
MethodFinder, in particular, kind of blew me away:
irb> MethodFinder.show( "hello", 5 ) "hello".length == 5 "hello".size == 5 => ["length", "size"] irb> MethodFinder.show( "foo", "foobar", "bar" ) "foo".< <("bar") == "foobar" "foo".concat("bar") == "foobar" "foo".+("bar") == "foobar" => ["< <", "concat", "+"] irb> MethodFinder.show( 3.14159, 3 ) 3.14159.round == 3 3.14159.truncate == 3 3.14159.to_i == 3 3.14159.prec_i == 3 3.14159.floor == 3 3.14159.to_int == 3 => ["round", "truncate", "to_i", "prec_i", "floor", "to_int"]
(though of course, this could be extremely dangerous in the wrong hands)
(HT: Coda Hale, Concentration Studios, and Andrew Birkett)
Clearly, Ruby has inherited much of the power of its Smalltalk heritage. When developer coding time is a priority, anonymous message passing with a method_missing handler is a Good Thing.
In general, dynamic, weakly typed languages – with all of their drawbacks – have always been my favorite coding environment. I’ve rarely felt too much enforcement of type safety to be worth the costs, though trust me that I do understand the reasons for it. It is rare that I find an object’s type to be ambiguous outside of classic ASP.
Conclusions
Though I’ve been playing with Rails on the side for a few months, I’m really only just getting my feet wet. I’m sure that there are aspects of the framework which will put me off; its Unicode support is poor (though that has gotten better in 1.2), raw performance is very poor (fingers crossed that a VM will be completed sooner rather than later), and DHH will probably continue to attempt to push away the enterprise market. But at the same time, I’m looking forward to getting my hands dirty in what is really still a very new framework, despite being over two years old. Thinking about architecture with the new CRUD features and ActiveResource alone should keep my mind occupied in between SICP and Latin.