Tesugen

Ruby and coding conventions

I’ve been toying with the Ruby language this weekend, writing a little program for generating my weblog locally instead of relying on a CGI script on the server. I like Ruby more and more. Particularly that it allows you to write really elegant, easily read code. Unfortunately, there’s a lot of swinish Ruby code out there, probably due to it’s being of script language heritage, adopting a lot of things from Perl.

The Perl aestethic doesn’t appeal to me, although I realize that the “hack factor” is important to many people. In Perl, the virtue is (or at least seems to me) to be able to do something in the fewest lines of code. To me, readability and understandability is more important and I appreciate code that clearly expresses it’s intent. It’s probably possible to write Perl that is readable, but the language doesn’t quite encourage it.

Ruby’s syntax is very free, but if you think about your coding conventions, you could write really clean and readable code. I’ve experimented with this a bit, and it seems that a convention is emerging – although it might be perceived as non-standard by the Ruby community. (I really like it when the best coding standard is the one that the creators of the language use – like the case is for Objective-C or Java, in my opinion – but I feel that you can achieve something better with Ruby.)

One thing with Ruby is that you can choose how to use parentheses. You can do it Java-style, entries = Dir.entries("/tmp").grep(/.txt$/); or you can use no parentheses, entries = Dir.entries "/tmp".grep /.txt$/. The latter is less readable in my opinion, because you make “chained” invocations. If you only make one invocation, though, I’m in favor of no parentheses: entries = Dir.entries "/tmp".

For me, it’s important that the coding convention is consistent and intuitive. If you go for “no parentheses”, you should never use parentheses. However, in Ruby you have method overloading, so in order for parsing to work with no parentheses, you would sometimes have to break a chain of invocations into several lines. I don’t like “sometimes” in coding conventions (unless the “unless” is intuitive) so that would have to be “always” in this case – always one invocation per line – but I don’t like that either.

Instead, you could do it Smalltalk style: entries = (Dir.entries "/tmp").grep "/.txt$/" – that is, to enclose the entire invocation in parentheses. I think this is much more readable than Java style:

def entries<br /> &nbsp;&nbsp;&nbsp;entries = (Dir.entries @directory).grep /.txt$/<br /> &nbsp;&nbsp;&nbsp;entries.sort! do |a, b|<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(File.mtime "#{@directory}/#{b}") &lt;=&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(File.mtime "#{@directory}/#{a}")<br /> &nbsp;&nbsp;&nbsp;end<br /> &nbsp;&nbsp;&nbsp;entries[0..@maximum_entries - 1]<br /> end


When it comes to names, I am used to using mixed case (or “CamelCase” as I saw it called yesterday), after having programmed mostly in Objective-C and Java. But the built-in Ruby classes uses names_like_these (and often heavily abbreviated) and I think mixed case blends badly with this. One objection I saw against the “all lowercase, words separated with underscores” style, was that longer chains of invocations are hard to read:

a_long_name.another_long_one.do_something


That is, that you easily mix up the underscores with the dots. I agree with this, but if you use the “no parentheses unless when chaining invocations or passing invocations as arguments” style, this is less of a problem. And I think that the fact that the Ruby classes use the “all lowercase, with underscores” convention speaks loudly in favor of this option.

Although I’m of the opinion that coding conventions must be consistent and intuitive, I’m not saying that they have to be extensive. My opinion is that they should be as small as possible. I’ve seen too many coding convention documents with lots of rules (and exceptions to those rules) – which still fail to cover all exceptions, and therefore sometimes yield in really strange code constructs just to obey the convention. The most important part of a coding convention is the way you name your methods and classes. All other things are not that big a deal, as long as all programmers value readability over hackish compactness.

The above was posted to my personal weblog on June 3, 2002. My name is Peter Lindberg and I am a thirtysomething software developer and dad living in Stockholm, Sweden. Here, you’ll find posts in English and Swedish about whatever happens to interest me for the moment.

Posted around the same time:

The seven most recent posts:

  1. Tesugen Replaced (October 7)
  2. My Year of MacBook Troubles (May 16)
  3. Tesugen Turns Five (March 21)
  4. Gustaf Nordenskiöld om keramik kontra kläddesign (December 10, 2006)
  5. Se till att ha två buffertar för oförutsedda utgifter (October 30, 2006)
  6. Bra tips för den som vill börja fondspara (October 7, 2006)
  7. Light-Hearted Parenting Tips (September 16, 2006)
Bloggtoppen.se