Saturday, March 10, 2007

Seeing Rails as a domain-specific language PART2: in syntax

A common Rails idiom we’ve already seen, and that you may have seen before, is this: has_many :editions
The syntax used here, with a verb-based directive on the left and what looks like a configuration spec on the right, seems like it could have been created specifically for a system like the Rails framework.
In fact, it’s a simple Ruby method call. The name of the method is has_many, and the argument is a Ruby symbol object. Every time anyone uses this method, it will look essentially the same.

You’ll almost certainly never see this send("has_many", "editions".intern) which is equivalent to the previous example (send is a do-it-yourself way to send a message to an object; intern converts a string object to a symbol object).
This send-based version is, admittedly, far-fetched enough not to be a close call. But you’ll probably never even see this much more slight variation on the original: has_many(:editions).
Many Ruby programmers like to put parentheses around method arguments, even when the parentheses are optional. But when writing Rails applications, even these programmers don’t use the parentheses—not because of Ruby (Ruby doesn’t care), but because leaving the parentheses off is a standard Rails convention.

The common idioms you use in Rails aren’t alternatives to Ruby; they’re alternatives within Ruby.
Long before Rails came along, it was possible to call a method with a symbol argument: method_from_ten_years_ago :symbol. And when Rails did come along, it—that is, its creator, core developers, and developer community—settled on this style of calling such a method. Ruby, mean while, is happy; this method-call style is a mainstream, idiomatic Ruby technique.

Part of learning Ruby as a Rails practitioner is recognizing what’s going on in your code, and the first lesson is that what’s happening is always Ruby. If you see thousands of has_many :editions and never see send("has_many", "editions".intern) or even has_many(:editions), it’s not because Rails has special syntax or rules, but because the Rails community has had the sense to rally around some coding conventions, gaining visual uniformity and a de facto language specificity for Rails development.

No comments: