rubocop / ruby-style-guide

A community-driven Ruby coding style guide
https://rubystyle.guide
16.46k stars 3.4k forks source link

bitwise vs. logical operators for boolean arithmetic #300

Open aspiers opened 10 years ago

aspiers commented 10 years ago

| and || both work for boolean arithmetic, e.g. in

some_flag = false
some_array.each do |element|
    some_flag ||= do_something(element)
end

||= could be interchanged with |=. Similarly with & and &&. However, traditionally the single character operators | and & are used for bitwise arithmetic, whereas the double character operators || and && are used for boolean arithmetic. I can't think of a good reason for breaking from this tradition, whereas adhering to tradition follows the Principle of Least Surprise, therefore I'm considering submitting a pull request to add this guideline. However I'd welcome other opinions before I do so.

bbatsov commented 10 years ago

:+1: Sounds good to me.

mvz commented 10 years ago

If some_flag is not a boolean, the behavior of | and || are very different.

aspiers commented 10 years ago

@mvz That's exactly the point I was making.

mvz commented 10 years ago

@aspiers D'oh, the whole bit about 'traditionally' threw me off, and I totally missed 'for boolean arithmetic' at the top.

aspiers commented 10 years ago

Haha, no worries ;-)

jmanian commented 7 years ago

It's also worth noting that even in the realm of boolean arithmetic they're not strictly equivalent. Namely the boolean operators will short circuit, and the bitwise operators will not:

# executes the predicate
true | predicate_with_side_effect?

# does not execute the predicate
true || predicate_with_side_effect?

This could actually have a lot of unintended effects for using |= instead of ||=. For instance in your original example if some_flag is already truthy then ||= would skip execution of do_something while |= would cause do_something to execute.