Jun 25 2006
Ruby on Rails: One Thumb Up, One Thumb Down
I’ve been playing around on Ruby on Rails, and my conclusion is that while it’s still an improvement over Java/Tomcat, it’s not the glorious grail of web development that the buzzword-media would have you believe.
On the one hand, there’s Ruby. Ruby is a language which is almost awesome. Here’s the pros:
- It is genuinely object-oriented, as opposed to Java (e.g.: try “2.toString()” in Java). Literals are objects, methods are objects, etc., etc. The result is that a lot of the crap that developers shouldn’t be worrying about (e.g.: boxing and unboxing) is finally able to be genuinely ignored without littering your code with. I’ve always wondered why Java didn’t do this from the get-go, and why C# bothered implementing easy means for user code to force boxing/unboxing. If everything’s an object, programmers should simply treat everything like an object — leave it to the compiler/VM to do the funny optimizations. That’s Ruby’s take, too, and I like it.
- Ruby provides Perlish array and hash constructors. This is not just some syntactic sugar, but a major win for functional programming. In Ocaml, for instance, it’s easy to talk in the code about arrays of tuples of tuples of arrays. The beautiful part of this is that you can then define recursive functional calls that you apply to this structure, and a highly efficient wavefront application means. In Java, you awesome get object-bloat, when you start defining a large number of classes to address all these relatively simple cases, and coding those objects takes up a lot of time (particularly if you have a strict unit testing regimine).
- Ruby allows you to pass code (including closures) around with ease. It’s actually easier than in Perl, which is nifty. And the functional/applicative programming style is built into the language so far that the Pickax book (the O’Reilly book on Ruby) declares that loops are almost always the wrong answer in Ruby. About time people figured out how ugly loops are…
- Ruby has a nifty way of making reference to “that thing called Foo”, similar to Perl’s nameglob (”*Foo”) operator. This makes it very easy to write code about other code, which makes it easy to implement and work with attributes and the like. It’s also kinda like passing a variable by reference, but without some of the nightmares that causes.
But there are some catches.
- There is no type safety system. I mean, everything’s an object, and you’ve got inheritence for objects, and all this awesome stuff, but you’ve got strictly dynamic typing. And dynamic typing taken to the point where they don’t even allow you to suggest that a particular argument should abide by some kind of contract. All your standard maintenence nightmares ensue — the biggest one being the “sleeper cell code”, which is only executed when the leap day lands on a Wednesday for the year you’re calculating, and THEN your application explodes for seemingly no good reason at all.
- The syntax is a little bit too clean. If I am having to parse the language based on whitespace and formatting (which the compiler kinda-sorta-but-not-really ignores), then the compiler is going to have trouble. I never considered putting a semicolon at the end of the line to be an onerous duty — in fact, I kinda liked it, because I’m the king of multiline statements in Java. That’s out the door. Parenthesis can be used sometimes to denote which arguments belong to which method, but it’s just begging for trouble.
And Ruby on Rails — that nifty web application development system currently seducing managers and buzzword-susceptible geeks — has got a similar kind of pros and cons.
Pros:
- MVC structure is forced, which is nice. The natural way to do things in Rails is the pragmatic and sane way to do web development.
- It provides all the nice features that a web applications server provides — database-driven sessions, preprocessor classes, postprocessor classes, mark-up language level code for dynamic *ML generation, application language level code for heavy lifting, etc., etc. And it’s easier to implement this stuff and plug it into Rails than it is to develop it on Java and plug it in through Tomcat.
- The convention-over-configuration model is a major pro. It means that as long as you’re staying within the rules, it’s easy to plug new features in, to get the system talking to a database, to respond to changes quickly, and generally to do rapid development.
Cons:
- Yes, it is easy to get something up-and-running right away. As long as you’re using Linux and MySQL, that is, like looking at the ugly template code generated by Rails, and either use the WEBrick or lighttpd. I’m yet to be convinced that the long-term maintenance cost of Rails-via-Apache is any cheaper than Tomcat-via-Apache, and I’m almost certain the performance is worse, even with FastCGI.
- The strong emphasis on convention-over-configuration leads to some serious with-us-or-against-us issues. Any deviation from convention is penalized by arbitrary, awkward, and generally confusing error messages. My favorite is the “undefined constant” error message that you get if you try to define a model with a plural name — a “users” model (representing the collection of all users) is a violation of convention, because models should always have singular names. If you try to do it, the error message is a stack trace through code the user never wrote with the message “undefined constants ‘users’ in users.rb”.
Ultimately, my conclusion is that Ruby on Rails is nice for small web portals, and while it’s better than Tomcat, it’s not better for all the reasons being touted. You still have to be just as much of an adept to get a Tomcat web application built as to get Ruby on Rails web application built: the difference is that Rails has its pain in the actual coding/development neck of the woods, whereas the pain of Tomcat is all in the infrastructure.
Popularity: 2% [?]

All engineering is tradeoffs. It’s a lot easier to get conceptual cleanliness if you can take other aspects- like performance- out of the equation, i.e. it doesn’t matter how much performance suffers to get that cleanliness.
And performance suffers- take a look at Ruby’s performance results on The Great Computer Language Shootout. Ocaml weighs in at 64% the speed of C, Ruby 5%. Ocaml is one of the fastest non-C-like languages (i.e. not including C, C++, or D). Ruby’s performance is down with SmallTalk and PHP, it’s slower than Perl, it’s slower than TCL.