August 10, 2007

Why use parens in Ruby?

Here is another ruby gotcha. Ruby allows you to skip parenthesizing method calls. These two lines are equivelent:

set_table_name "users"
set_table_name("users")

In some cases this will make your code mildly more readable. In practice though this is dangerous. Consider this code:

if arr1.include? "foo" && !arr2.include? "bar" then
  # do something
end

Ruby order of operations says that && will be evaluated prior to calling my_array.include?. So first you evaluate:

"foo" && !arr2.include? "bar"

Which always returns true or false. Then you evaluate;

if arr1.include? true
  # do something
end

Which is clearly not what you intended. This code is correct:

if arr1.include?("foo") && !arr2.include?("bar") then
  # do something
end

As a rule, you should never call a function without parenthesizing the parameters. Even if you are writing code which is not in an IF statement or is in an IF statement, but is not a part of boolean logic, you should still parenthesize it because it is possible someone else will come along and change your code not realizing this gotcha exists. Code defensively, use parens.