vinibol12
vinibol12

Reputation: 468

What's the difference between "or" and | in ruby?

I thought the only difference was between | and || where | would be equivalent to or. But I realised the latter is incorrect and now I'm confused.

AMEND: I understand this question to be different from ruby bitwise or while mine is about the lack of understanding of the difference between bitwise and boolean operators as pointed out here in comments and answers. Besides, in my opinion the answers to this question have been more relevant and clearer to the problem itself. Flagging as duplicate would dissuade users from the better answers.

Upvotes: 3

Views: 1119

Answers (2)

tadman
tadman

Reputation: 211600

The | operator is a binary mathematical operator, that is it does a binary OR and works on a numerical level:

1 | 2
# => 3
4 | 3
# => 7
1 | 2 | 3
# => 3

This is because it's manipulating individual values as if they were binary:

0b01 | 0b10
# => 3 (0b11)

The || operator is a logical one, that is it returns the first value that's logically true. In Ruby only literal nil and false values evaluates as logically false, everything else, including 0, empty strings and arrays, is true.

So:

1 || 2
# => 1
0 || 1
# => 0

The or operator works almost exactly the same as || except it's at a much lower precedence. That means other operators are evaluated first which can lead to some problems if you're not anticipating this:

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

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

This is because it's actually interpreted as:

(a = false) or true

This is because = has a higher precedence when being evaluated.

Upvotes: 4

Jörg W Mittag
Jörg W Mittag

Reputation: 369458

|| and or are special built-in operators. Which means they could (and indeed do) have behavior that cannot be expressed in Ruby. In particular, || and or are non-strict and lazy in their right operand, whereas Ruby is actually a strict and eager language.

OTOH, | is just a method call like any other method call. There is absolutely nothing special about it. Which means:

  • it is strict
  • it is eager
  • any object can choose to respond to it however it wants

Whereas || and or are language built-in operators, which are

  • non-strict in their right operand
  • lazy in their right operand
  • their behavior is hard-coded and independent of any particular object, it is always the same and cannot be changed

The only difference between || and or is precedence: or has very low precedence (and it has the same precedence as and).

Upvotes: 1

Related Questions