148

Are not and ! synonyms, or are they evaluated differently?

1

3 Answers 3

211

They are almost synonymous, but not quite. The difference is that ! has a higher precedence than not, much like && and || are of higher precedence than and and or.

! has the highest precedence of all operators, and not one of the lowest, you can find the full table at the Ruby docs.

As an example, consider:

!true && false => false not true && false => true 

In the first example, ! has the highest precedence, so you're effectively saying false && false.
In the second example, not has a lower precedence than true && false, so this "switched" the false from true && false to true.

The general guideline seems to be that you should stick to !, unless you have a specific reason to use not. ! in Ruby behaves the same as most other languages, and is "less surprising" than not.

Sign up to request clarification or add additional context in comments.

5 Comments

I have used 'not' in the past to make negated conditionals easier to read. Meaning if the entirety of the conditional should be negated I felt comfortable using 'not' rather than '!'. I like it when my code reads like inglush
@jaydel Could you use unless in that case?
@Jacob, yes, definitely. unless is just not really favored in the ruby world. The general consensus is that it just gets in the way when ! works just as well in most situations. I'm sure there are cases where unless may be more expressive, but I steer clear.
I disagree that unless is disfavored. The closest thing we have to a consensus says otherwise.
Just wanted to share an example of how surprising not can be. In Python, I sometimes assign booleans to variables to make if-statements easier to read. That might mean using the pattern x = not y, where y is something complex. In Ruby, x = !y works, but x = not y gets syntax error, unexpected tIDENTIFIER, expecting '('. The precedence order means this needs parentheses around the right of the assignment op to work: x = (not y).
22

An easy way to understand the not operator is by looking at not true && false as being equivalent to !(true && false)

Comments

2

I have an RSpec-driven example here: Ruby's not keyword is not not but ! (not)

In essence:

  • They differ in precedence
  • They are not aliases
  • ! can be overriden, whereas not cannot be overriden
  • when you override ! then not will be overriden too, hence it must be using ! under the hood

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.