[RAD stands for Ruby Ape Diaries, of which this is part VIII.] Programming is supposed to be an engineering discipline, or maybe a branch of mathematics. But, as Don Box memorably said: “the only people who should do it are those who can't not do it”, calling us “those few people who absolutely must live in the world of executable abstractions”. One consequence is that we’re passionate about the content and the form. Herewith some remarks on appearances; the way Ruby code looks and how you store it and so on; issues as important, perhaps, as any other.

As I wrote a few days ago, Ruby has a TMTOWTDI culture; for anything that’s worth doing, there are lots of different ways. This has made me alternately uncomfortable and happy.

Files · When I’m Rubying, I have to think about how to deal the code out into files. A few years of Java have apparently atrophied the part of my brain that does this. In Java, for those who don’t know, if you’ve got a class called com.textuality.Lark, the source has to live in com/textuality/Lark.java, and the compiler will generate com/textuality/Lark.class, and that’s all there is to it. If you’re living in an IDE like NetBeans, this means that you totally never think about files; you think in terms of classes and packages and the IDE puts the code where the code needs to go.

In Ruby, it’s perfectly legitimate (and common) to have four or five different classes, perhaps only loosely related, in a file. I’ve done it, my REXML-for-Java stand-in has Element and Attribute and Document classes all in one file and it seems natural and convenient.

Even if you wanted to, you probably couldn’t impose a Java-like discipline because in the middle of your FishFrying module you might decide to add some new methods to File or String.

Still, I’m not entirely convinced that it’s a good use of my time to think about where to put the code.

Names · Which is better, removeCamisole or remove_camisole? In Java, you never have to ask yourself this question because the first option, “lowerCamelCase”, is so deeply wired into the culture that doing anything else would amount to egregious abuse of anyone who might have to maintain the code you write.

Ruby uses CamelCase for classes and leans to underbars elsewhere; although I’ve run across a few instances of CamelCase in method and module names. In the Ape code, I started up doing things in the Java style, but pretty quickly decided this was wrong, and have tried to stay in underbar territory, although there are a few lingering camels in the underbrush.

I think that for JRuby, in particular, this convention should be taken very seriously, so that by looking at something’s name you’ll know which side of the fence it comes from.

Parentheses · This one drives me nuts. I have actually spent nontrivial amounts of time looking at my code and agonizing over whether some method call should have them or not.

It’d be tempting to impose a simple policy: Parentheses always! Because this kind of thinking seems like a waste of time. On the other hand, the judicious omission of parentheses is one reason that Ruby code can be so readable. It seems pretty clear to me that for straightforward conditionals, compulsory parentheses are just static. Here are some ifs from the Ape code:

if uri =~ /^https?:/
if type == 'text' || type == 'html'
if collections.length > 0

On the other other hand, as a matter of principle I have refused to learn the precedence rules of any language I’ve ever used, and applied a Draconian policy of parenthesize-on-the-slightest-doubt. Once again, from the Ape:

if (!found_entry_coll) && collection.accept.index('entry')

But it’s method calls and declarations where the to-()-or-not-to-() angst really bites. One-argument calls and declarations generally don’t seem to need parentheses, with the exception of Whatever.new(foo), where they for some inchoate reason feel necessary. Do zero-argument calls ever need parentheses? I think not.

I went through the Ape code and looked at all the places where I’d put parentheses on one-argument calls, and they were all either new or some sort of factory method, or “retrieval” methods that take an arg and emit a value:

ids << entry.child_content('id')

Maybe the right answer is to figure out how to turn these into instances of [] so I’d be saying entry.child_content['id'] and not sweating the parentheses.

Domain-Specific Languages · The Rubyists are always talking about creating them and what a great thing this is. As far as I can tell, they’re mostly just pimped-out method calls without benefit of ().

Readability · It’s all about readability. It’s really all about readability. Code is maintained much longer than it’s written, and anything that makes it more readable is a really, really big deal.

Readability is important enough that maybe it’s OK that I have to stop and think about parentheses.

Readability is important enough that Ruby is right to allow, and Java wrong to forbid, the use of nil as false and non-nil as true in conditionals, so Ruby allows this useful, highly-readable idiom, originally invented for C:

if handler && handler.check_content(message)

(Note that Perl is wrong in allowing "" and 0 to stand for false, as I think most PerlMongers would now agree.)

Readability is important enough that incorporating Perl’s abbreviated-conditional syntax is good:

return true unless content_type == 'application/atom+xml'

Readibility is important enough to make Ruby’s method/block idiom a better way to iterate than anything else I’ve seen anywhere.


author · Dad
colophon · rights
picture of the day
August 26, 2006
· Technology (90 fragments)
· · Dynamic Languages (45 more)
· · Java (123 more)
· · Ruby (93 more)

By .

The opinions expressed here
are my own, and no other party
necessarily agrees with them.

A full disclosure of my
professional interests is
on the author page.

I’m on Mastodon!