Chad Perrin: SOB

15 January 2010

the unnecessarily single-lined Ruby idiom

Filed under: Geek — apotheon @ 11:49

I keep seeing a one-line expression of a particular Ruby idiom. I think it ends up looking ugly and a bit difficult to grasp as it is usually written. I recently decided to see if it still works if done on multiple lines — and it does.

I most recently ran across it in two places. One was the Ruby Best Practices book (great book so far, by the way). The other was a Weblog post by John Nunemaker called Class and Instance Variables in Ruby. In the latter, he explains that this idiom can be used to create class instance variables which — unlike class variables — are per-class specific. By contrast, the scope of a class variable (not a class instance variable) extends across the class in which it is defined and its subclasses. Anyway, his example of creating a class instance variable with accessor methods looks like this (with an extra semicolon added by me for clarity):

class Polygon
  class << self; attr_accessor :sides; end
  @sides = 8
end

After playing in irb, I discovered that the fact everyone else in the world seems to want to do this in one line isn't a result of not being able to spread it across multiple lines. Considering the one-line construction in this case looks ugly as hell to me, I'd rather have written that code like this:

class Polygon
  class << self
    attr_accessor :sides
  end
  @sides = 8
end

I don't, in fact, see any reason to cram it all into one line like that. There are times when something with a clear multiline form like this probably should be done in a single line — such as when you want to create an iterator block that only contains a single line of code:

array.each {|x| puts x }

The multiline approach would of course look like this:

array.each do |x|
  puts x
end

I think that, in a case like this, the single line form is clearer. There's a distinct single line form for a block in Ruby, though. The example of the class instance variable's accessor, on the other hand, does not have a distinct form well suited to a single line. Rather, one has to just manhandle code line terminators (the semicolons) so that Ruby won't throw errors when cramming everything onto a single line — and it ends up looking cluttered, especially when there's a symbol involved with its leading colon.

Am I the only person that thinks this way — that the class instance accessor is clearer in a multiline form than strung together on a single line? Is there some benefit to doing it all in a single line that I just haven't seen?

7 Comments

  1. I'm totally with you on this. There are plenty of times when terseness is good, like making stuff visually line up. And I agree that spacing things out just looks cleaner, has more room to breathe. But the real reason why I space things out is because over time there is always new code that sneaks in and it's a lot easier to just splice it in between two lines vs. some point in a compound line.

    Comment by Amy — 18 January 2010 @ 08:55

  2. I completely agree — mostly because I dislike "end" at the end of a line.

    Comment by Chip Camden — 18 January 2010 @ 02:46

  3. In RBP, it's likely that at one point in the writing process, I collapsed that code into one line to prevent a pagebreak in the code. I don't generally think it's a nice way to write it, though it probably doesn't look as bad to my eyes as it might to yours.

    But you're right, it looks better expanded and there is no technical reason not to.

    -greg

    Comment by Gregory Brown — 29 January 2010 @ 07:29

  4. Amy:

    Sorry I never got around to acknowledging your comment before this. I don't recall off the top of my head seeing you comment here before, and I like to welcome first-time commenters, especially when they contribute something useful to discussion. Hopefully you'll notice this response from me, this late in the game.

    In this particular case, I think the technical "What if I need to add more later?" reason you bring up is not as important to me as the aesthetic. Readability is, to me, pretty much the prime concern for code formatting. I do agree with your desire to make things easier for later additions or adjustments, though, even if that's not my primary reason for preferring the multiline version.

    Gregory Brown:

    Thanks for commenting! I'm glad you offered your input on the subject — and I'm still really enjoying the book, when I'm not too tired to read it. I've been using it as my nightstand reading, and lately I've been pulling a lot of all-nighters, though I think I'll be able to get back to it more next week.

    I looked up the code snippet again, on page 73 of my copy. From the look of it, unless you were adjusting for some effect several pages later, it doesn't look like the intent was to avoid a page break in the book. Then again, it's always possible the layout got changed later, I suppose. I probably should have considered the space-trimming that tends to inevitably occur in well-written books to keep them under page count limits as a possibility, too, though as I mentioned this isn't the only time I have seen that particular idiom crop up.

    Regardless of the reason it ended up that way, though, it's a very minor thing in the context of the book. It's just a stylistic tendency that I have seen several times (your book being one of the most recent) that I don't really get.

    Anyway, thanks again for contributing, and more so for writing such a great book in the first place.

    Comment by apotheon — 30 January 2010 @ 12:12

  5. oh, now I see the example and you're right, this was intentional :)

    To me there is a difference between:

    # something I don't like to do
    class << self; attr_accessor :x; end
    

    and

    # something I have no problem doing
    def singleton
      class << self; self; end
    end
    

    No particularly good reason, aside from convention. Interesting point though, now that I think of it. I guess that the idiom for getting at the singleton class is just something I've seen often enough that it seems to have that meaning to me, so it is actually visually helpful rather than jarring. But that comes with the requirement of already being used to seeing it that way...

    Comment by Gregory Brown — 1 February 2010 @ 11:12

  6. Whoa, formatting fail. Please feel free to turn those into comment lines.

    Comment by Gregory Brown — 1 February 2010 @ 11:12

  7. Thanks for the update. I guess I don't really have any particular feeling that there's much of a difference between the two cases, though now that you point out that you do see it as being different I'll probably think about it every time I come across that situation in the future (whether reading someone else's code or writing my own) and see if I eventually start seeing some advantage in differentiating between the cases like that.

    I appear to have lost my note above the comment text area that said comments use Markdown formatting. Oops. I fixed the formatting on that.

    Comment by apotheon — 1 February 2010 @ 11:46

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

All original content Copyright Chad Perrin: Distributed under the terms of the Open Works License