Do I Need (These Parentheses()?)
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
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 fact 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
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
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 literally, we can figure out the next exception: no arguments means parentheses aren't needed. So it's:
"james".capitalize # not "james".capitalize()
[ ].empty? # not [ ].empty?()
Now, because you're probably using them often, we will relax the rules on
p(). You can leave them off those calls, as long as you are following the rest of these rules. That lets us to write:
puts "Something to print..." # not puts("Something to print...")
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) || obj.is_a?(WhateverElse) # ... end
Finally, beware of the gotchas. If you have a bunch of
||s 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