Difference between "or" and || in Ruby? [duplicate] - ruby

This question already has answers here:
Difference between "and" and && in Ruby?
(8 answers)
Closed 3 years ago.
What's the difference between the or and || operators in Ruby? Or is it just preference?

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.

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:
and, or and not have much lower precedence than &&, || and !
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.

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")

puts false or true --> prints: false
puts false || true --> prints: true

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.

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 ||.

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 ||.

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 ||.

Related

Ruby `&&` vs `and` in a block [duplicate]

This question already has answers here:
Difference between "and" and && in Ruby?
(8 answers)
Closed 6 years ago.
In the code below, if I replace the and in the any? statement with &&, it throws an error unexpected tIDENTIFIER, expecting '}'.
def ArrayAddition(arr)
i = 2
until i == arr.length
combinations = arr.permutation(i).to_a
return true if combinations.any?{|array| array.inject(&:+) == arr.max and !array.include? arr.max}
i+=1
end
false
end
What is going on here? Does Ruby handle these operators differently?
The operators and and && have different precedence, and are not equivalent. As such, the Ruby Style Guide advises against using and and or operators: The and and or keywords are banned. It's just not worth it. Always use && and || instead.
Due to the difference in precedence, the other operators in the expression have higher or lower comparative precedence. In this case, the argument for the Array#include? call end up binding to the wrong expression.
You can solve this by adding parentheses around the argument to the Array#include? call.
Yes. and has lower precedence than && (and almost everything else). This expression:
foo and bar baz
...is parsed like this:
foo and (bar baz)
...so Ruby knows foo is a method name (because it can't be anything else). On the other hand, this expression:
foo && bar baz
...is parsed like this:
(foo && bar) baz
...which just doesn't make sense and you get a syntax error.
Generally speaking you should use && unless you specifically want and's lower precedence, so in this case the easiest fix to the syntax error is to use parentheses around the method argument:
foo && bar(baz)
...and so:
array.inject(&:+) == arr.max && !array.include?(arr.max)
As a bonus, this is more readable as well.

What happens with further conditions if first one is `false`?

I often face the situation when if condition A (for example !#object.nil?) is false, condition B, when checked, can raise an error (for example #object.some_method -> undefined method 'some_method' for nil:NilClass).
I tested it in console, but could't get some full data.
1) Is it safe to use and/&& when if first conditional is false, second can lead into an error?
2) What about or?
!#object.nil? && #object.some_method
#object && #object.some_method
Both of the above are valid patterns in Ruby. You will not get the "undefined method for nil" error, because the expression to the right of the && is never evaluated if the expression to the left of it evaluates to nil (or false).
You can also accomplish this check using postfix if or unless:
#object.some_method if #object
or
#object.some_method unless #object.nil?
are both valid alternatives.
Regarding or:
Using || (Rubyists generally avoid the keyword or operator) will not protect you from the error, because when the expression on the left side of the || evaluates to nil, the interpreter will actually continue on and attempt to evaluate the expression on the right side.
Second part of these lines will never be exected:
false && raise "this will never be raised"
true || raise "this will never be raised"
In your case, if you are using active support, you can do:
#object.try!(:some_method)

Difference between "not" and "!" in ruby

Are not and ! synonyms, or are they evaluated differently?
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.
An easy way to understand the not operator is by looking at not true && false as being equivalent to !(true && false)
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

What does the '||=' operator do in ruby? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does ||= mean in Ruby?
I'm new to ruby and I saw this being used in one of the answers here:
RACK_ENV = ENV['ENVIRONMENT'] ||= 'test'
I couldn't find any reference to the ||= operator...
here is the article which explains it really good.
« Ruby, concurrency,... | Main | How does one update... »
The curious case of the Ruby T-Square operator.
By prashant on Dec 14, 2008
The "||=" operator is interesting, both in what it does as much as in how it's widely used in Ruby land. The operator does not do what you would usually expect. i.e.,
a ||= expr
is not the same as
a = a || expr
The evaluation happens to be
a or a = expr
and the difference is important in at least one use case [0]
As a little DTrace script will verify, this operator is not implemented is a method(or anywhere in Ruby land) and is intrinsic to the VM. The reason is performance, and the fact that the entire expression does not have to be evaluated to yield a result when you're 'OR'ing:
"Ruby's Boolean operators are built into the language and are not based on methods: classes, for example, cannot define their own && method. Ruby defines special true and false values but does not have a Boolean type. method. The reason for this is that Boolean operators can be applied to any value and must behave consistently for any kind of operand."
. . .
"Another reason that Ruby's Boolean operators are a core part of the language rather than redefinable methods is that the binary operators are "short-circuiting." If the value of the operation is completely determined by the lefthand operand, then the righthand operand is ignored and is never even evaluated."
https://blogs.oracle.com/prashant/entry/the_ruby_t_square_operator
what does || do? If you have a and b then a || b is true if and only if either a or b is true. It is the same with ||= this operator combines two operations '=' and '||'. So a ||= b is equivelent to c || c = b
EDIT: so in your context ENV['ENVIRONMENT'] ||= 'test' means that if ENV['ENVIRONMENT'] is not nil and not false it will preserve its value, otherwise it will become 'test' and after that the new value of ENV['ENVIRONMENT'] is assigned to RACK_ENV

|| Operator, return when result is known?

I have a function similar to the following:
def check
return 2 == 2 || 3 != 2 || 4 != 5
end
My question is, will Ruby perform all the comparisons even though the first is true, and thus the function return true. My checks are much more intensive, so I'd like to know if I should break this out in a different way to avoid making all the checks every time.
irb(main):004:0> 2 == 2 || 3 != 2 || 4 != 5
=> true
Thank you.
Ruby uses short-circuit evaluation.
This applies to both || and &&.
With || the right operand is not evaluated if the left operand is truthy.
With && the right operand is not evaluated if the left operand is falsy.
|| short-circuits as soon as the first condition is true. So yes, it will help if you put the most expensive conditions at the end.
|| will by default short-circuit evaluate, meaning that once the first "true" expression is encountered it will stop evaluation (unless you explicitly state you want all expressions to evaluate with the 'or' operator).
reference:
http://en.wikipedia.org/wiki/Short-circuit_evaluation
As soon as one of the condition is true, the function will return.
You can test it yourself in irb, like this:
irb> p('Hello') || p('World')
As we know the function p prints its parameters(in an inspect manner) then returns them, so if the || short circuits, only "Hello" is printed, otherwise both "Hello" and "World" are printed.
You can also test the logical && operator, by using puts instead of p, as puts always returns nil.
BTW, irb is a perfect place to play around ruby. You can test everything there, except a small portion of concurrency.

Resources