Do I Need (These Parentheses()?)

Posted over 5 years ago in Early Steps and Ruby Tutorials.

If you came to Ruby via the Learn to Program book or just don't yet have a consistent set of rules for when you do and don't need parentheses in Ruby code, this post is for you.

I have nothing against Learn to Program, just to be clear. A member of my family is learning Ruby from it and it's going pretty well. I recommend it. However, Chris is a little inconsistent with his use of parentheses in the code samples, and worse, he doesn't really give you a good set of rules to decide when to make the choice. No problem. Let me give you the rules.

I'm a chess player. In learning chess, you really go through two phases. First, you learn the rules of strategy. These will make you good because the rules are designed to help you avoid common mistakes. Now, to get great, you go through the second phase: learning when to break the strategy rules. Ruby is exactly the same.

Here's the only rule of strategy you need to learn to get good: methods need parentheses around their arguments.

So you want to write:

def my_method(args, go, here)  # not def my_method args, go, here
  # ...
end

and:

my_method(args, go, here)  # not my_method args, go, here

I'm serious. That's it. You're good now. Congratulations! Wasn't that easy? If you've had enough learning for one post, call it an early day and be secure in the fast that you are now knowledgeable in the Way of the Parentheses. If you have some energy left, read on and I'll make you great...

First, let's talk about what's not a method call. Mainly if and while are keywords in Ruby and they don't require parentheses. When you add them, we laugh behind your back and call you a Java programmer. So it's:

while condition  # not while (condition)
  # ...
end

and:

if condition  # not if (condition)
  # ...
end

OK, here's another easy one. I said the rule was, "...need parentheses around their arguments." If we take that literal, we can figure out the next exception: no arguments means parentheses aren't needed. So it's:

"james".capitalize  # not "james".capitalize()

and:

[ ].empty?  # not [ ].empty?()

Now, because you're probably using them often, we will relax the rules on puts() and p(). You can leave them off those calls, as long as you are following the rest of these rules. That let's us write:

puts "Something to print..."  # not puts("Something to print...")

or even:

p rand(100)  # not p(rand(100))

One last exception. The question methods read very prettily without parentheses and beautiful code is always a good goal, so drop them in simple conditionals with just one question and argument. For example:

if obj.is_a? Whatever  # not if obj.is_a?(Whatever)
  # ...
end

Beware of that last one though. If the condition is getting complicated, add the parentheses:

if obj.is_a?(Whatever) or obj.is_a?(WhateverElse)
  # ...
end

Finally, beware of the gotchas. If you have a bunch of ands and ors in a conditional, use parentheses to set the order just as you would a math statement. Also, watch out for this:

puts((1 +2) * 3)  # not puts (1 + 2) * 3
acrylic added 36 minutes later:

Here is a rule I follow:

When you are calling a method without an explicit receiver (like a method in your class) and it takes no parameters, use parentheses or add an explicit receiver (self). It is very confusing sometimes if you do not.

class Foo
  def some_method
    blah() # not blah
    self.blah # careful, won't work if #blah is private
  end
  def blah
    ...
  end
end

user_input = gets() # not gets
user_input = STDIN.gets
null added about 14 hours later:

Although I agree with thesee rules in general, it's interesting to point out that Rails (specifically the Rails documentation) seems adamantly against parantheses, (and braces on hash tables...)

Although it makes their code almost read like English, it can be hard to understand what exactly is going on if you're new to Ruby (it seems that quite a bit of Rails programmers jump right in knowing no Ruby beforehand)

Any insight?

Sudo Nimm added about 14 hours later:

Yeah, Rails has a lot to answer for in this regard, IMHO, although at the same time I've written DSL type stuff myself that's just looked better without parens. Maybe it's just because like null said, a lot of Rails programmers see Rails before Ruby. Ho hum...

James Edward Gray II added about 17 hours later:

These rules are my opinion of what's correct. Obviously, others, including the Rails core team, may not agree with me 100%. I try to worry more about whether I am doing things right.

Also, I'm pretty sure Ruby herself agrees with me:

$ ruby -w -e 'puts rand 100'
-e:1: warning: parenthesize argument(s) for future version
48
Simen added 2 days later:

My only rule of thumb is whenever ruby or I have problems parsing a method call, I add parantheses. It works pretty well.

James H added 2 days later:

Given that I've been doing a lot of Rails lately and that I rather like dropping the parenthesis when possible, the rules I tend to follow are much in line with your own, however, I also tend to think of whether or not my method call is a statement, or a request for a resource. For instance:

# link_to() is a statement: you want the end result, not access to a resource
link_to "Link Text", :action => "some_action"

# find() is accessing a resource
User.find(:first, :conditions => ["username = ?", username])

I always use parenthesis in documentation, without exception.

Harry added 29 days later:

Last example could mention that

puts((1 +2) * 3)

and

puts ((1 + 2) * 3)

and

puts (1 + 2) * 3

work out OK

but

puts(1 + 2) * 3

is not working (by default).

Considering puts' speciality I'm not even sure which one from the first three is the best.

Jim added about 1 month later:

Your rules seem to say

my_attr=(0)
is preferred to
my_attr= 0
I don't think I agree.

James Edward Gray II added about 1 month later:

Jim: Very good point there. I treat equal method accessors as operators and I only use parenthesis for those as needed. Good catch.

Gavin Kistner added 2 months later:

Similar to Jim's comment, if you're going to update your suggestions, you might want to include the #[] and #[]= methods as no-paren aspects, also.

James Edward Gray II added 2 months later:

Again that falls into the operators category with me, so yes we don't need parenthesis with those.

Macario Ortega added over 3 years later:

I grown used to not using parenthesis around args in method definitions or when calling methods is just the habit but now I find easier to read, so my rule is:

I use parenthesis only when there is abiguity.

I find it liberating and stetically pleasing not having all those parenthesis and curly braces. The downside is that I find it harder to adjust to other people's style when colaborating.

I agree with James H: I allways use parenthesis in documentation because is the most common habit.

franco added over 5 years later:

is there any benefit to any of this? @Macario_ortega got this right.

I use parenthesis only when there is abiguity ...

The minimal use of params should be to disambiguate expressions in the language's syntax i.e the parser. Additional use should aid human clarification.

Human clarification cannot be determined by this (or any other) finite set of rules. The best effort to improve clarity is by observation and critical thinking.

Ruby gives us the freedom to express a concept in multiple forms. Rules like these extinguish thinking about clarity, do they not?

James Edward Gray II added over 5 years later:

Obviously, programmers will reach a point where they can distinguish which "rules" to follow in which scenarios, eventually. Until then, they exist to give us guidelines that are meant to help us.

I'm very for freedom and critical thinking, but I also see a lot of new programmers writing Ruby that doesn't look like Ruby. That hinders their ability to participate in the community and get help, so there are tradeoffs.

Add Your Thoughts

You can use Markdown in the body of your comment to format text and make links.

Note that I reserve the right to edit any content you post here. I typically exercise this right to fix formatting issues. All posts must be approved so spam will never be seen on these pages.

Author:
URL or Email (optional):
Body: