Elements of Ruby Style
Next week marks the publication of the 50th Anniversary edition of the Strunk & White's The Elements of Style, a critically important work for anybody who puts words together on a regular basis.
In that spirit, here are some thoughts on good Ruby & Rails style -- I'm mostly focusing on Ruby-specific guidelines here. This is somewhat closer to a brain dump than a fully-baked style guide, so it's something I intend to come back to, especially after hearing everybody tell me exactly where I'm wrong, wrong, wrong.
UPDATE: There were some comments about the formatting being messed up. Apparently whatever tool we're using for code coloring doesn't work well with Safari. In Firefox, the formatting is as intended. We've cleaned this up -- thanks for your patience.
The goals of well-styled code are correctness and simplicity, in that order.
I don't want to pretend that it's not important for code to be correct. Still, I think that functionally correct code is not the last step. For me, the best order is: Make it Work, Make it Clean, Make it Fast (if necessary).
Ruby code should be indented two spaces.
This should be uncontroversial, right? Indenting Ruby code four spaces indicates that you are a very recent convert from Java.
I also think that ERb and HTML within ERb should be indented two spaces. Indentation inside an ERb Ruby block should be aligned with the ERb delimeter, not the the Ruby statement, so this:
<% if something %> two spaces <% end %>
Not this:
<% if something %>
too many spaces
<% end %>
Statements that extend past 80 characters or so should be broken up and indented on the following line.
This one may be a little idiosyncratic, since I tend to use a narrower edit window than a lot of people. That said, it's still a good idea to have a hard right margin to your code. Whether it's 80 or 100 characters is less relevant than that all of the code can fit on the screen without scrolling. If you have to scroll to see code, eventually, you'll make mistakes based on code that you can't all see at once. (I find this especially true in HTML/ERb, where you can easily mangle a closing tag in column 125 and lose your mind trying to find the problem).
There are two possibilities for indenting the second part of a long line. The first, which is the one recommended in Code Complete, is to double indent it compared to the top line:
a_very_long_method_name(argument1,
a + b, arg 3)
The other is to indent to the level of the parenthesis in the statement, like Emacs Lisp does:
a_very_long_method_name(argument1,
a + b, arg 3)
In either case, you should never break up individual sub statements -- in the above examples, never split up a + b -- you should try to keep entire expression, hash or array arguments on the same line even if that means the line above is shorter.
Anyway, both choices have tradeoffs. The double-indent is the easiest to maintain as the code changes, but can make it tricky to follow the logical structure of the code. The longer indent makes it generally clear what goes together, but it's a little hard to keep up, and can look kind of ragged.
I tend to prefer the first form for Ruby, although I do use the second sometimes, especially for, say, hash options inside a larger statement.
Ruby allows you to leave out parenthesis, in general, resist this temptation.
Parenthesis make the code easier to follow. General Ruby style is to use them, except in the following cases:
- Always leave out empty parentheses
- The parentheses can be left out of a single command that is surrounded by ERb delimiters -- the ERb markers make sure the code is still readable
- A line that is a single command and a single simple argument can be written without the parenthesis. Personally, I find that I do this less and less, but it's still perfectly readable. I tend not to like single lines in regular ruby code that have multiple arguments and no parentheses.
- A lot of Ruby-based Domain Specific Languages (such as Rake) don't use parenthesis to preserve a more natural language feel to their statements.
Use if statements as expressions.
Not this -- it's overlong, kind of redundant, and not in the spirit of Ruby as I understand it:
if boolean x = 3 else x = 5 end
But this:
x = if boolean then 3 else 5 end
I prefer the use of the explicit if statement to the ternary operator. In the case where the if statement becomes too long to fit on one line, I tend to indent to the level of the if statement:
x = if boolean
then 3
else 5
end
I also tend to keep the then in the line, although it's technically not needed.
Use of Ruby idioms
There are a couple of idioms that, although they are sort of opaque the first time you see them, are commonly used enough that they should be used in place of wordier alternatives. Right now the list starts at three:
||= as in, @user ||= User.find(params[:id])
&&= as in, @user.name &&= @user.name.downcase
Symbol#to_proc as in, array.map(&:upcase)
I realize some people don't like Symbol#to_proc -- I really do, though.
Only use trailing if statements in guard clauses.
Ruby lets you write statements that are only executed conditionally UPDATED for syntactic correctness
return if x.nil?
In general, these statements can get hard to read (people tend to overlook the if part) and should only be used if:
- The statement and the conditional are both simple
- The statement is a guard clause that prevents execution of the rest of the method -- this can save a level of indent and make the method easier to read
Multiple return statements are fine. But in Ruby, you can leave off the last one.
You will sometimes read people who say that a method should only have one return statement. I disagree with that -- I'd rather get out of the method early if the data is wrong then have the guts of the method indented inside an if statement.
In Ruby, every method returns the value of its last expression, so you only need to explicitly include a return statement when you are bailing out of a method. That's a useful enough distinction that I don't use the actual return statement on the last line of code even if it's a simple statement of the return value.
Block Layout
The convention is braces for single line blocks and do/end for multi-line blocks:
list.map { |x| x + 3 }
list.map do |x|
x + 3
end
I'm okay with using braces for a multi-line block if you are using the result of the entire statement in a chain (but see below):
list.map { |x|
x + 3
}.sort
Stringing things together
Ruby tends to encourage stringing method results together, especially for a bunch of enumeration methods:
all_users.select(&:is_active).map(&:name).sort
Although you can go overboard with this, I think it's okay as long as the logical chain makes sense as a single operation -- I'd avoid it if it was genuinely chaining through a series of different objects (I probably would avoid doing something like user.manager.company.name.size as a single line).
Anyway, if this goes over a single line, that's the time to break the chain up into two statements.
Now what
What'd I miss? What's wrong?
Topics: Ruby on Rails
Comments: 48 so far
Leave a comment
About Pathfinder
Follow the Blog
-
Get a monthly update on best practices for delivering successful software.
Subscribe via email
Subscribe via RSS
Categories
Topics
Archives
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006
- August 2006
- July 2006
- June 2006
- May 2006
- April 2006
- March 2006
Blogroll
Recent
- Aesthetics and Web Design
- Asterisk-Java Testing with Groovy
- 3 Misuses of Code Comments
- Fluently NHibernate
- Digging a Hole and Covering it with Leaves — The Software Development Version
- The Importance of User Experience - Do You Understand It in Your Bones?
- Writing Your Own Protocol With NSURLProtocol
- What’s In Your Dock: iPhone edition
- Feature Fatigue
- ChicagoRuby meeting ‘Test Prescriptions’ recap


I still use do/end instead of the braces when tacking a method call on to the end of a multiline block.
list.map do |x|
x + 3
end.sort
Comment by Dan Manges, Friday, October 17, 2008 @ 4:54 pm
Should “return if x = null” be “return if x == nil” ? And if so, I also tend to adopt the JavaScript style of putting the constant first. So …
return if nil == x
That way if you forget the second equal sign, the interpreter throws an error.
Comment by Harry, Friday, October 17, 2008 @ 4:55 pm
This is great Noel!
I’d also quickly add:
Use ‘and’ not ‘&&’
Use ‘or’ not ‘||’
Comment by Chris O'Sullivan, Friday, October 17, 2008 @ 5:39 pm
This was a good read - a clear, terse summary of the formatting you see in most good Ruby code. I just have one small quibble:
x = if boolean then 3 else 5 end
might just be better expressed using the ternary operator:
x = boolean ? 3 : 5
Comment by Norman Clarke, Friday, October 17, 2008 @ 5:41 pm
Whitespace errors waste people’s time. They make diffs overly noisy and can cause needless merge conflicts. There should be no whitespace at the end of a line or file. Your editor should display whitespace errors and your source control system should not allow files with whitespace errors to be committed without some explicit confirmation step.
Comment by Ryan Tomayko, Friday, October 17, 2008 @ 5:49 pm
Great article, could be expressed as ruby code conventions.
Comment by khelll, Friday, October 17, 2008 @ 5:51 pm
Seems like your indentation isn’t showing up - kinda ironic for an article about style….
Comment by chris, Friday, October 17, 2008 @ 6:13 pm
2 spaces? 80 columns? Are you kidding me? What are you in 80×25 text mode on a 386? That’s barely any indentation at all on a large display. Barely even noticeable. I’d have to concentrate to notice that indentation.
Comment by Brandon, Friday, October 17, 2008 @ 6:29 pm
Definitely a good guide. Perhaps a ’school’ of proper ruby style should be started, that lists example programs, code snippets…and of course can make fun of horrible code.
Comment by Nick Quaranto, Friday, October 17, 2008 @ 6:40 pm
@3: ‘and’ and ‘or’ have some subtle precedence issues. They are useful in places but it is recommended to use &&, ||.
Comment by Russ, Friday, October 17, 2008 @ 8:44 pm
i didnt get into 2-space soft tabs in textmate until i converted to haml in rails from erb. now i’m hooked, and use 2 spaces for tabs even in erb-laden rails projects.
i dunno about that 80 column limit though. i find that breaking up longer lines makes for some un-sexy code, since it’s usually just a handful of text being moved.
Comment by lowell, Friday, October 17, 2008 @ 8:56 pm
I don’t agree with the if statement being long and overredundant and not in the spirit of ruby. That style of if statement is extremely quick and easy to read, especially if the code inside the if statement is complex. The chained method on the multiline blocks are starting to slide into getting cute and clever vs. clear and easily readible IMO. I think my standards would clash with yours and maybe these standards come down to personal taste?
http://blog.objectmentor.com/articles/2008/06/26/now-and-for-something-completely-different
Comment by Tim Case, Friday, October 17, 2008 @ 11:58 pm
[...] of the attempts to summarize good coding practices into a guideline that I stumbled upon this week: The Elements of Ruby Style. It’s obviously incomplete, but it’s a good start that has all chances to evolve. There [...]
Pingback by Weekend Ruby: Coding Quality with Style | noizZze, Saturday, October 18, 2008 @ 5:26 am
Anyone who doesn’t use 3 spaces for indentation is in error.
Comment by Carla Nielsen, Saturday, October 18, 2008 @ 6:44 am
Ruby way:
return if x.nil?
instead of
return if x == nil
Comment by Alin, Saturday, October 18, 2008 @ 7:00 am
Python, not just Java, prefers 4 space indentation according to PEP 8.
Comment by Mike, Saturday, October 18, 2008 @ 9:35 am
“I probably would avoid doing something like user.manager.company.name.size as a single line”
hu ? how many lines then ???
Comment by jerome, Saturday, October 18, 2008 @ 9:57 am
Hi Noel,
I enjoyed your post. Some observations:
= Parentheses
The general rule for parentheses is to use them in functional expressions, leave them out in statements, e.g.
x = o.func(args)
o.meth args
= Use if statements as statements
Did you mean ‘Use if statements as expressions’?
Neither of your alternatives for if statements are ‘idiomatic’ - ‘then’ is almost a deprecated keyword. Perhaps this:
x = if boolean
3
else
5
end
but then you might as well use the ternary ?: operator:
x = boolean ? 3 : 5
By the way, using if as an expression confuses a lot of Ruby newbies. Why add to the cognitive load? At best, it’s a tricksy little flourish.
= Use of Ruby idioms
Symbol#to_proc is currently a Rails idiom, not a Ruby one. Also, the Rails implementation is incredibly slow. That’s why some people don’t like it.
= Only use trailing if statements in guard clauses
Surely you mean:
return if x == nil
= Multiple return statements
Seeing any ‘return’ in Ruby code makes me sigh. Maybe OK for a quick exit after parameter checks.
= Block layout
The braces vs do … end convention is that braces are used in functional expressions, do … end in statements, e.g.
result = list.map{|x| … }
list.each do … end
Nothing to do with how many lines they go over. It just so happens that most Rubyists don’t like semi-colons, so they make a do … end block go over multiple lines to avoid them.
= Stringing things together
To clarify your point: chaining is fine on enumerable methods that return enumerables - you’ll always have an enumerable to act on. Chaining is not such a good idea where any intermediate method may return nil (your second example) which is also a violation of the http://en.wikipedia.org/wiki/Law_of_Demeter (though this can be overstated).
Regards,
Sean
Comment by Sean O'Halpin, Saturday, October 18, 2008 @ 10:40 am
@Chris O’Sulliva: ‘and’ and ‘&&’ is not really the same… There are several good blog posts about this allready.
Comment by Ingemar, Saturday, October 18, 2008 @ 8:00 pm
[...] http://www.pathf.com/blogs/2008/10/elements-of-ruby-style/ : un coding style guide pour Ruby. [...]
Pingback by Dev Blog AF83 » Blog Archive » Veille technologique : 37 Signals, OOo 3.0, MAMA, Tag Maps, CSS3, benchmarks, Merb, Monday, October 20, 2008 @ 12:20 pm
[...] Pathfinder Development » Elements of Ruby Style (tags: syntax styleguide style rubyonrails ruby rails programming development coding) [...]
Pingback by links for 2008-10-20 | Libin Pan, Tuesday, October 21, 2008 @ 1:14 am
This is a great article.
A couple of points:
if boolean
x = 3
else
x = 5
end
is much clearer than:
x = if boolean then 3 else 5 end
So what is you save 4 lines?
I agree with the comnment that the second one is overly cutesy.
Someone said ‘and’ is better, and someone else said that ‘&&’ is better. Which is correct?
Comment by Glenn, Tuesday, October 21, 2008 @ 3:53 pm
Interesting topic for an article and useful writeups are always appreciated and shine on the author. Thank you! Value of your article is tremendously diminished by the fact none of the examples actually work (formatting not applied). Lack of proofing (to notice the errant examples) is a real disappointment; conveys you don’t care about your work and/or the readers.
Comment by JT, Tuesday, October 21, 2008 @ 11:33 pm
I’ve never seen ruby code that uses “then” that wasn’t over three years old. It’s unnecessary and should be omitted.
Symbol#to_proc is not part of Ruby 1.8, so it should only be used in Rails apps, and even there you take a perf hit so it shouldn’t be done in tight loops.
For do/end vs {} blocks, another common rule of thumb is to use do/end when you’re performing an operation for its side-effects and {} when it’s meant to be used for its return value. This usually is in sync with the single/multi-line rule, but not always.
Comment by Phil, Wednesday, October 22, 2008 @ 6:09 pm
return if x = nil
This code is buggy.
Comment by Bob Aman, Thursday, October 23, 2008 @ 9:16 am
Chris O’Sullivan is wrong to suggest using “and” over “&&” and “or” over “||”. The “and” and “or” operators have extremely low precedence and should only be used for flow control. That IS what they were designed for after all. Using them instead of their counterparts leads to bugs, most often with assignment.
It may be tempting to make your code read more like English, but that should not be your goal. Remember, “the goals of well-styled code are correctness and simplicity, in that order.”
Comment by Bob Aman, Thursday, October 23, 2008 @ 9:29 am
“There should be no whitespace at the end of a line or file.”
+1
Re: Phil and Symbol#to_proc
I disagree. It has its place outside Rails apps. Since Ruby 1.9 supports it, it’s a no-brainer for legitimate usage in Ruby 1.8 as well. However, as usual, one should not require ActiveSupport to obtain the functionality.
Comment by Bob Aman, Thursday, October 23, 2008 @ 9:37 am
@Sean: “By the way, using if as an expression confuses a lot of Ruby newbies. Why add to the cognitive load? At best, it’s a tricksy little flourish.”
I agree that not everyone would want to use it, but it can have a clear semantic meaning and maybe even contribute to readability. To me, the following means “by the time this chunk of code is over, we’ll know what ‘body_mass_index’ is:”
body_mass_index = if person.gender == male
# some math
else
# some different math
end
I use this structure if the code in the if-statement has no real side effects and I just care about the result. Then I can see at a glance what this section does.
Comment by Don, Thursday, October 23, 2008 @ 9:58 pm
2 spaces is the same as no indentation. The discussion could be between 8 or 4 spaces. I definitely prefer 4 spaces.
2 spaces is insane!
Comment by blaxter, Friday, October 24, 2008 @ 6:03 am
[...] language fans, I’m fascinated by programming as communication, and therefore also by thing like style guides that bridge the gap between the formal requirements of the compiler and the cognitive needs of the [...]
Pingback by Pathfinder Development » Ruby Stylista, Friday, October 24, 2008 @ 3:06 pm
I vote for 21.7 spaces.
Comment by bubba, Friday, October 24, 2008 @ 11:34 pm
[...] Pathfinder Development » Elements of Ruby Style [...]
Pingback by เร็วส์ หกสิบหก » นั่งเทียนเขียนข่าว#20, Sunday, October 26, 2008 @ 3:49 am
I prefer to not have a space after the curly bracket for block arguments. {|foo| foo.bar }, not { |foo| foo.bar }
Comment by leethal, Monday, October 27, 2008 @ 7:33 am
Sentences that start with “You should…” normally loose me at the ’should’
Comment by Apie, Monday, October 27, 2008 @ 7:34 am
Call me crazy, but I think this
a_very_long_method_name(
argument1,
a + b,
arg 3
)
looks much better than this
a_very_long_method_name(argument1,
a + b, arg 3)
or this
a_very_long_method_name(argument1,
a + b, arg 3)
Comment by Joe Zack, Monday, October 27, 2008 @ 7:54 am
I have to say that in the following code:
all_users.select(&:is_active).map(&:name).sort
‘is_active’ is violating my feelings
Using prefixes like ‘is_’, ‘get_’ and ’set_’ is so java (and yes, java is a synonym for ugly here). In ruby instead of prefixing with ‘is_’ you’d use the postfixed questionmark, e.g.:
all_users.select(&:active?).map(&:name).sort
Regards
apeiros
Comment by apeiros, Monday, October 27, 2008 @ 8:02 am
2 spaces is the only way to go. For one, not everyone uses TextMate (big shock to many, I know). Even for those who do, many times it is just as easy to use a CLI editor for a quick fix. Dealing with 4/8 spaces in that context is “insane”. I can’t imagine what kind of res/font size you would be using to not notice a 2 space indent… That said, this is really a project-by-project issue, where the team decides what standard to adopt. That said, when it comes up, in a “tab vs whitespace” debate, whitespace wins. And it’s usually the 2 space variety. This is often a LCD issue, and older coders will chafe at tabs and blanch at >2 space indents. Since you like your older coders, you go with them.
In terms of ternary operator, the author provides no legitimate reason not to use it. The justification is “I don’t like it”. This is ridiculous. The ‘? : ‘ operator is quite definitely a “Ruby idiom”, and is significantly more readable then the overly-verbose single-line example given.
Comment by ab5tract, Monday, October 27, 2008 @ 11:00 am
[...] highlights two useful posts about Ruby style (here and here) and includes a link to reek, a popular tool for sniffing out code smells. [...]
Pingback by ESPN Dev Blog » Blog Archive » Ruby Style Guides and Tools, Monday, October 27, 2008 @ 11:22 am
“Indenting Ruby code four spaces indicates that you are a very recent convert from Java”
nice argument!
Comment by dani, Monday, October 27, 2008 @ 3:07 pm
From vBharat.com » Pathfinder Development » Elements of Ruby Style…
Here are some thoughts on good Ruby & Rails style — I’m mostly focusing on Ruby-specific guidelines here. This is somewhat closer to a brain dump than a fully-baked style guide, so it’s something I intend to come back to, especially after hearing ev…
Trackback by vBharat.com » Pathfinder Development » Elements of Ruby Style, Monday, October 27, 2008 @ 6:20 pm
Please divorce your current editor if it hides code on long lines. Any programmer’s editor will do the correct thing and wrap.
Comment by Nona, Monday, October 27, 2008 @ 9:06 pm
[...] week, Noel Rappin of Pathfinder Development wrote Elements of Ruby Style - an attempt at producing a Ruby “style guide.” After some initial feedback to this, [...]
Pingback by Ruby Style Guides and Tools: How to Write Good Looking Ruby : WebNetiques, Tuesday, October 28, 2008 @ 4:55 am
2 spaces? no way. 80 char limit? no way. Standard if structure is much clearer than the proposed alternatives. Avoid ternary? Pfft, don’t think so–especially for short lines. Leave out last return? Don’t care for that at ll. Code should be explicit wherever possible. return x is instantly recognizable as to purpose and function. Stringing things together goes “overboard” very quickly IMO. smaller steps on more lines is usually easier to read than one-liner magic.
I like Ruby, but I don’t care for a lot of the style and idioms that are completely counter to most other languages and practices just so the people using them can be the “kewl kids.” Worse is the flogging certain community folks give when their arbitrary favorite style isn’t followed. It feels a lot like royal manners–designed to make a small group feel elite because they follow some arbitrary rules. It’s just style snobbery and doesn’t fit within the usually friendly atmosphere of teh Ruby community (slowly being eroded as elitism spreads).
Comment by gw, Wednesday, October 29, 2008 @ 2:03 am
@gw:
Most Ruby users that I know care deeply about the “look and feel” of the language they use - that’s the whole reason they love Ruby so much. Efforts to come up with the “best practise” for writing clear, understandable, good looking code are not elitism or an effort to become “cool kids”. It’s more an effort to arrive at some kind of ideal standard form, by people who care deeply about style and function.
And more than 2 spaces is ridiculous. Maybe 4 spaces is necessary for Java, a much more verbose language, else the indentation gets lost in a sea of code .. but Ruby is far more concise. 2 spaces is fine in well written code.
Also, I disagree that Ruby is becoming less friendly. There’s a few new corporate wannabe wankers around, sure, but you get that anywhere. The ruby people I know are friendly as anything. Calm down, cheer up and have a little more faith in people.
Comment by Sho, Friday, October 31, 2008 @ 2:44 am
[...] Elements of Ruby Style - Ruby Stylista - [...]
Pingback by เร็วส์ หกสิบหก » นั่งเทียนเขียนข่าว#22, Sunday, November 2, 2008 @ 12:18 pm
[...] Elements of Ruby Style [...]
Pingback by Juixe TechKnow » The Rubyist: October Edition, Friday, November 14, 2008 @ 2:16 am
@Harry,
Maybe even
return if x.nil?
Comment by Barry, Friday, November 14, 2008 @ 11:38 pm
Of course the beauty of using tabs for indentation is that your editor will display them at whatever width you prefer, while not imposing your own width preferences on others.
For the record, I do single-tab indent and display them with a width of four characters. Everyone wins.
Comment by Kenn, Friday, December 19, 2008 @ 8:33 pm