I have to admit that my first reaction to Ted Neward’s blog about Rails was the same as Dion’s and Justin’s: “Ted’s missing the point.” But his followup has mostly changed my mind. Ted’s still skeptical, which is a good thing, but what he thinks he sees in Rails, and what he’s looking for, is (to my mind) the right thing, and my belief is that he’ll find it there.
Ted writes: “Look, guys, at the end of the day, if Rails is about Ruby and the things that a scripting language can do that a compiled, statically-typed language can’t, then Rails definitely has a place in the world and I’ll take the time to learn it.” My position is that that’s precisely what Rails is about. Sure, some of the lessons that Rails teaches can be carried across to statically-typed languages just fine, but some of the most important ones simply won’t translate. Rails is a testament to the power of dynamic languages in general, and of Ruby in particular.
Here’s one example: it’s a mistake Ted did make in his first blog, and it’s a mistake others make as well. “I mean, I see a bunch of intelligent code-generation,” Ted wrote, and if you’re coming from a static language background it’s easy to look at Rails’ scaffolding support and default views and think that’s what you’re seeing. I thought so, too. If that’s what the scaffolds are, they aren’t too impressive—partly because that’s easy to do, but mostly because generated code like that eventually becomes a burden. Most of us have seen code generation tools before, and they’re great for getting started, but when you move beyond what the generated code will do for you you’re in a world of hurt, often having to throw away what’s built into the framework and supply your own versions of everything.
But Rails isn’t doing “intelligent code-generation”—unless what you mean by that is that it’s doing the least possible code generation. Crack open those scaffolds and look inside. They’re almost empty! Usually they’re just trivial class definitions, with no methods or fields. All of the behavior comes at runtime, through inherited reflective logic. Rails is generating structure, not behavior, and that turns out to be a huge win. Ruby makes that possible, partly through its rich support for runtime reflection, but mostly because its dynamic, open nature makes it a breeze to fill in those empty spaces incrementally, overriding and extending little by little the default behavior that’s built into the framework.
And that’s just one example of how a dynamic language makes Rails possible, and why some of Rails’ goodness is easy for we static-language types to miss at first glance.
What’s Rails about?
- It’s about Ruby and the things that a scripting language can do that a compiled, statically-typed language can’t.
- It’s about confirming some of the earliest thinking about frameworks: that they should be extracted from well-designed applications, rather than being designed on their own.
- It’s about demonstrating the fundamental importance of the DRY principle for software design. (Bruce Eckel calls it “the most fundamental concept in computing.”)
- Oh … and it’s about bringing the pendulum back away from the layers-upon-layers default approach in Java projects.