Previous Myths:
Rails enthusiasts and detractors seem to agree on one thing: Rails embodies a lot of good ideas about web development, and other frameworks are changing to be more Rails-like. If my Java web framework of choice is already adopting Rails' good ideas, why should I bother looking at Rails itself?
This myth is a tricky one, because it is partially true. Many of Rails' good ideas can be copied into any language. But some of Rails' good ideas require a language as open as Ruby--so much so that the good ideas in Ruby become bad ideas in other languages. If you copy Rails' good ideas into Java, you will get somewhat less that half of the total value. And if you do not understand Ruby, you will not even know what you are missing. Let's consider some examples.
Some of Rails' good ideas can easily be copied into almost any framework. Take convention over configuration. There is nothing language-specific about this idea, and it is great to see other frameworks moving in this direction.
Other good ideas depend on specific Ruby features. Rails uses open classes to make better, more readable object models. For example, you can say x.blank? instead of StringUtilities.isBlank(x). Individually, such differences do not matter much, but hundreds of them add up to a significant improvement in readability.
A more important use of open classes is creating simple, domain-specific languages (DSLs), such as ActiveRecord's declarative relationships and validations:
class Poet < ActiveRecord::Base has_many :poems validates_presence_of :name end
DSLs often use open classes twice: first to create new declarative "statements" that are legal at class definition time, and second to add new methods depending on the options chosen. You could simulate some of this with Java annotations, but it would take more work. How much more work? Look at the source code for Rails validations side-by-side with Hibernate or Spring validations.
A few of Rails' most controversial ideas are good only in the context of Ruby, and would be bad ideas in Java. For example, many Java web applications have a clean, layered separation of business logic and persistence. This is good idea in Java, in case the application has to change. Rails applications seem to compromise this separation, choosing instead to emphasize simplicity and ease of development. This is a good idea in Ruby, because it is easy enough to add this separation when and only if you need it. (I will say more about this in a subsequent post.)
Finally, we come to the best idea in Rails: Flexible, open languages enable rapid innovation and exploration. What languages will we use to think the big software ideas of 2008?
Comments
Good post! Agree to most of your claims, except the one on separation of business logic and persistence. I always felt that the compromise that Rails makes by coupling the domain model along with the persistence model works well in simple applications with not-so-rich domain logic. In case the domain is complicated and user requirements / business rules change (and which they do very often), then a separate domain model always gives you the flexibility and mileage.
Regarding the language of 2008, I think Scala is shaping up pretty well too and it nicely integrates with the JVM, more seamlessly than JRuby.
Yes, I agree, ‘openness’ of Ruby makes it a good choice for inovations such as intention revealing DSLs of Rails. But we (developers in the Java world) have received a ‘gift’ in the form of Groovy language, and with its Meta Object Protocol, etc. it’s now totally possible to implement similar powerful features such as DSLs, etc. (thanks to Grails):
class Poet { static hasMany = [poems:Poem] static constraints = { login(name:false) } }
No wonder you like Rails so much more than Java. I definitely would not recommend separating business logic and persistence into different layers in Java. Tools like Hibernate give you the flexibility to evolve your object model independent of your relational schema (much moreso than ActiveRecord). If you separate the layers, all you’re doing is coding a bunch of adapter logic by hand instead of letting Hibernate do the work for you.
I’m starting to think you left Java for Rails a couple years ago and you think the Java world just stood still. First you compare Rails to Struts 1 (2 is out!) and now this. Of course Rails is going to look better if you compare it to 5-year-old tech!
Data is Data period. You should not try to force data into some easier to read language pattern. It is more fun to code than a custom parser, but oh so much worse.
Now when you go to edit your data, instead of being in a separate true domain-specific file that you can parse and error check, you are stuck in some rubiesque half-language where the error reporting is horrendous and non-programmers must memorize strange :quirks and_patterns.in order to_structure! ( :their).modifications to_the data.correctly
Why not just put the language in a separate file where it belongs and write a parser for it? One with half decent error reporting-
perhaps even an eclipse plug-in. Then make it part of your toolkit where, like rails, it’s “complete” and not counted as part of your application code-then your Java code should be at least as short as Ruby code, possibly shorter. Also MUCH more readable, quicker to write, etc.If you want to truly compare Java and Ruby for ease of use, go to an environment where a fairly experienced team is working in either language and count the number of language text sitting at the desks, and examine how dog-eared each is.
I don’t know a Java programmer that has needed a language text past the first half-year. I don’t know a Ruby programmer that can do without one for a month.
There shouldn’t be gotchas and tricks in a language, the simpler a language can be, and still be expressive enough to solve the problem, the better.
ps. I also love the way Ruby pundits always pick horrible worst-case scenarios for their examples.
Because Java tries to simplify the language by not dumping every possible method into “String”, you pick on the never-used StringUtilities.isBlank(x). Why? Because comparing any of the more commonly used methods (the ones included in String) wouldn’t have come out very favorably because for the most part, the Ruby syntax really doesn’t get you much except in strange scenarios.
I have to admit that ruby is more Fun to write—albeit something I consider a guilty pleasure.
Hi Bob- My point is not so much about what architectural layers you use. Regardless of what they are, these layers tend to be chosen up-front in Java, because of the use of classes for encapsulation. I don’t dislike Java, as a platform it is world-class. As a language it is too low-level for most of the work that interests me.
Hi Bill- Whether blank? is part of String is not the point. It isn’t what methods are in, but who decides, that matters to me. See http://www.relevancellc.com/2007/6/1/object-models-not-what-but-who.
Bob, you’re pathetic …
The idea of separation of concerns is language agnostic and can be easily achieved in Rails as it can be in Java, as can collapsing of concerns. I think the point is simplicity here which bleeds back into the ideas of less code, more readable. The fact that Ruby allows method calls at any place in the code and that the classes are open is definitely powerful, but I think you deviated somewhat here and mostly re-iterated points you had already made. If you wanted to discuss the merits of separation vs. collapsing, we could argue that in smalltalk or objective-c for that matter.