210

What's the difference between the or and || operators in Ruby? Or is it just preference?

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
Alex Baranosky
  • 48,865
  • 44
  • 102
  • 150
  • 5
    See also [Difference between `and` and `&&`](http://stackoverflow.com/q/1426826/211563). – Andrew Marshall May 18 '12 at 06:10
  • 1
    For the semantics, see Avdi Grimm's [Using “and” and “or” in Ruby](http://www.virtuouscode.com/2010/08/02/using-and-and-or-in-ruby/) – Stefan Oct 25 '19 at 10:06

8 Answers8

299

It's a matter of operator precedence.

|| has a higher precedence than or.

So, in between the two you have other operators including ternary (? :) and assignment (=) so which one you choose can affect the outcome of statements.

Here's a ruby operator precedence table.

See this question for another example using and/&&.

Also, be aware of some nasty things that could happen:

a = false || true  #=> true
a  #=> true

a = false or true  #=> true
a  #=> false

Both of the previous two statements evaluate to true, but the second sets a to false since = precedence is lower than || but higher than or.

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
mopoke
  • 10,555
  • 1
  • 31
  • 31
90

As the others have already explained, the only difference is the precedence. However, I would like to point out that there are actually two differences between the two:

  1. and, or and not have much lower precedence than &&, || and !
  2. and and or have the same precedence, while && has higher precedence than ||

In general, it is good style to avoid the use of and, or and not and use &&, || and ! instead. (The Rails core developers, for example, reject patches which use the keyword forms instead of the operator forms.)

The reason why they exist at all, is not for boolean formulae but for control flow. They made their way into Ruby via Perl's well-known do_this or do_that idiom, where do_this returns false or nil if there is an error and only then is do_that executed instead. (Analogous, there is also the do_this and then_do_that idiom.)

Examples:

download_file_via_fast_connection or download_via_slow_connection
download_latest_currency_rates and store_them_in_the_cache

Sometimes, this can make control flow a little bit more fluent than using if or unless.

It's easy to see why in this case the operators have the "wrong" (i.e. identical) precedence: they never show up together in the same expression anyway. And when they do show up together, you generally want them to be evaluated simply left-to-right.

Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338
Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
  • 3
    This occasionally trips me up because in Perl, `and` does have higher precedence than `or`, reflecting `&&` and `||`. But usually you shouldn't chain long, complex series of these together anyways. – ephemient Jan 18 '10 at 03:12
  • 1
    Interesting, I didn't know that. I've never actively used Perl, nor learned it. – Jörg W Mittag Jan 18 '10 at 03:23
  • Good answer - I didn't know about the equal precedence thing, sounds like an accident waiting to happen. – klochner Jan 18 '10 at 20:54
  • 2
    Nope. `and` is always preferable to `&&` unless doing complex Boolean algebra. It's more readable. – Marnen Laibow-Koser Nov 02 '11 at 18:40
  • As far as the precedence issue, if you have more than one `and` or `or` without parentheses, your code won't be readable anyway and you should refactor it. – Marnen Laibow-Koser Nov 02 '11 at 18:48
  • In short, Jörg, you're wrong here. `if this_condition or that_condition` isn't Boolean algebra except in the most pedantic sense; rather, it's control flow and so is perfectly acceptable. – Marnen Laibow-Koser Nov 02 '11 at 18:50
  • 20
    **DON'T** listen to @MarnenLaibow-Koser - This has nothing to do with readability and everything to do with the fact that the precedence difference will yield different results in the most basic boolean operations: e.g. `true && false` != `true and false`, `false or true` != `false || true`. – Yarin Sep 13 '13 at 18:00
  • 2
    @Yarin Precedence only becomes an issue when you start nesting operations without parentheses. Your example of `true && false` is in fact basically equivalent to `true and false`, because there's no precedence issue. Likewise, `(x > 1) and (x < 4)` is operationally equivalent to `(x > 1) && (x < 4)`, because all the precedence is done with parens. In these cases, the choice is solely a readability issue. – Marnen Laibow-Koser Sep 13 '13 at 18:10
  • 2
    @Yarin Actually, your example doesn't show what you seem to think it does. `true && false` is equivalent to `true and false`. The differences in your example are solely due to implicit precedence issues: `print true and false` is equivalent to `print(true) and false`, whereas `print true && false` is equivalent to `print(true && false)`. You've proved my point rather nicely -- that precedence only comes into play when you meet operations without parentheses. – Marnen Laibow-Koser Sep 15 '13 at 17:31
  • 2
    @Yarin Apparently I was half-wrong here; it seems that `print(true and false)` is a syntax error, which I hadn't been aware of. – Marnen Laibow-Koser Sep 15 '13 at 17:33
44

and/or are for control flow.

Ruby will not allow this as valid syntax:

false || raise "Error"

However this is valid:

false or raise "Error"

You can make the first work, with () but using or is the correct method.

false || (raise "Error")
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Eadz
  • 1,363
  • 13
  • 12
  • 1
    er wondering why this got downvoted. The 2nd top answer states "the only difference is the precedence" but by my example you can see that is not the case. – Eadz Apr 09 '14 at 06:26
  • This does indeed seem to clearly demonstrate that the accepted answer is (very slightly) wrong. Is the behaviour you demonstrate here documented anywhere, to your knowledge? – Mark Amery Dec 03 '14 at 11:38
  • 5
    The fact that it's invalid syntax is a consequence of the operator precedence. raise doesn't return therefor it can't be evaluated as an expression. – bluehallu Jul 13 '16 at 14:01
15

puts false or true --> prints: false

puts false || true --> prints: true

mridula
  • 3,203
  • 3
  • 32
  • 55
Radek Secka
  • 318
  • 2
  • 11
10

The way I use these operators:

||, && are for boolean logic. or, and are for control flow. E.g.

do_smth if may_be || may_be -- we evaluate the condition here

do_smth or do_smth_else -- we define the workflow, which is equivalent to do_smth_else unless do_smth

to give a simple example:

> puts "a" && "b"
b

> puts 'a' and 'b'
a

A well-known idiom in Rails is render and return. It's a shortcut for saying return if render, while render && return won't work. See "Avoiding Double Render Errors" in the Rails documentation for more information.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Vadym Tyemirov
  • 8,288
  • 4
  • 42
  • 38
2

or is NOT the same as ||. Use only || operator instead of the or operator.

Here are some reasons. The:

  • or operator has a lower precedence than ||.
  • or has a lower precedence than the = assignment operator.
  • and and or have the same precedence, while && has a higher precedence than ||.
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
vel pradeep.MS
  • 584
  • 5
  • 7
  • I strongly disagree with that; `and` and `or` *do* have their place in control flow; for example, you can write `if a==b and c==d` and you can be sure that `and` has the lowest precedence. It also looks way nicer to people from outside the C world. – DarkWiiPlayer Apr 23 '18 at 14:24
1

Both or and || evaluate to true if either operand is true. They evaluate their second operand only if the first is false.

As with and, the only difference between or and || is their precedence.

Just to make life interesting, and and or have the same precedence, while && has a higher precedence than ||.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
cvibha
  • 693
  • 5
  • 9
-15

Just to add to mopoke's answer, it's also a matter of semantics. or is considered to be a good practice because it reads much better than ||.

rogeriopvl
  • 51,659
  • 8
  • 55
  • 58
  • 3
    I don't know if "good practice" is on the side of the or operator. The case is analogous to parens on arguments. Method calls often read nicer without, but they lead to strange bugs in certain cases. I used to selectively use or and drop parens, but eventually I just gave up on them because fairly often they could not be used, some of those times I forgot and introduced a bug, and came to prefer the consistency of just always using parens and ||. The situation is at least debatable. – tfwright Jan 18 '10 at 00:41
  • you mean it's a matter of syntax :) they both have the same semantic interpretation (modulo operator precedence) – klochner Jan 18 '10 at 00:43
  • 3
    If you are relying on precedence for Boolean arithmetic, then your code isn't readable anyway. Add parentheses or refactor. – Marnen Laibow-Koser Nov 02 '11 at 20:00
  • This should be a comment, not an answer. – the Tin Man Nov 22 '19 at 18:38