5

I have an if statement in my Rails app. I need to do a basic "if true and !false" sort of check. The expression is defined as:

ActiveRecord::Base.connection.tables.include? 'settings' && !Settings.setting_is_set?('defaults_set')

If I put that as my expression to an if, the if will not trigger. If I run that expression in the console, I get false.

Now, if I modify the expression to read:

ActiveRecord::Base.connection.tables.include? 'settings' and not Settings.setting_is_set?('defaults_set')

It returns true as it should, and the executes it's block.

So the question is: Why is 'expression && !expression' not behaving like 'expression and not expression'. It's my understanding && and ! should correspond to and and not almost directly.

What am I missing here?

  • More than likely this is due to operator precedence. I'm pretty clear on this in PHP and Python, but not Ruby - hopefully someone who knows Ruby better than I will come and explain how it works in Ruby. – JAL Feb 12 '10 at 01:40
  • This is an exact duplicate of http://StackOverflow.Com/questions/2083112/ – Jörg W Mittag Feb 12 '10 at 10:08

2 Answers2

6

Its because when you use && Ruby is interpreting the entire end of the string as a single argument being passed to include. Put parenthesis around the 'settings' and the first statement will work fine:

ActiveRecord::Base.connection.tables.include? 'settings' && !Settings.setting_is_set?('defaults_set')
# => false

ActiveRecord::Base.connection.tables.include?('settings') && !Settings.setting_is_set?('defaults_set')
# => true

Somehow, when you use and not it knows that the second part is not part of what is being passed to include and your call succeeds.

Doug Neiner
  • 65,509
  • 13
  • 109
  • 118
  • 7
    `and` has lower precedence than `&&`. This is a common ruby gotcha: http://stackoverflow.com/questions/372652/what-are-the-ruby-gotchas-a-newbie-should-be-warned-about – Andrew Grimm Feb 12 '10 at 01:56
  • I never use and/or, only &&/||. In most languages you expect these constructs to have high precedence; and/or don't. – Shadowfirebird Feb 12 '10 at 09:29
1

‘not’ is a control operator, ! is a logical operator. The difference is that ‘not’ has lower priority when evaluating the command. Use ! when you do logical expressions.

The Whiz of Oz
  • 6,763
  • 9
  • 48
  • 85