Difference between negation and inequality in Ruby? - ruby

What is the difference between if !variable == 10 {...} and if variable != 10 {...} in Ruby programming language? Of course this can be applied to all other languages. In first case are we just negating condition, and in second testing if variable is actually unequal to 10?

if variable != 10 is equivalent to unless variable == 10
while !variable is negating the variable, so first it's evaluated as an expression, then negated.
Example
variable = 5
variable != 10 # => true
!variable # => false (5 is evaluated to true, then negated)
!variable = 10 # => warning: found = in conditional, should be ==

To a large degree all programming languages, including Ruby, follow boolean algebra rules that state there's a number of ways to express the same condition.
x != y
!(x == y)
!!(x != y)
This also plays out in other domains, such as:
!x && !y
!(x || y)
As others have pointed out, be very careful when using the == comparator instead of the = assignment operator.

Related

One and only one zero comparison with the least operations

This might be a silly question, but in some function I have two int s, and need to compare them to find if exactly one of them is ==0... Both of the ways I came up with require 5 logical operations, and I can't think of anything shorter... Is there a shorter way?
What I came up with is:
int x, y;
if (((x==0) || (y==0)) && (x != y)){} // most obvious option, or:
if (((x^y) == x) ^ ((x^y) == y)){} // looks better, but still 5 ops
The expression ((x^y) == x) ^ ((x^y) == y) can be simplified in a straightforward way.
(x^y) == x if and only if y == 0, and likewise (x^y) == y if and only if y == 0. So the following uses three operations to compute the condition:
if((x == 0) ^ (y == 0)) {
// ...
}
This makes sense because using XOR as a logical operator, the result is true if and only if one but not both of the operands is true. So this directly tests whether one but not both of x == 0 and y == 0 are true.

How to convert logical statements into their opposites?

I have a scenario where I am checking whether to hide something depending on multiple variables values. For some these statements, if they evaluate to true, then I will skip over showing something (showing by default). However, I need to re-write my statements so that if they evaluate to true, then I will show something (hiding by default).
For Example:
If X !== 1 && Y !==1
For Example:
If X === 3 or Y === 3
If either example were true, then I would skip (hide) something.
I need to flip conditions the conditions written in the code so that the expressions are their opposites. I cannot just evaluate the original expression and then swap the end true/false result.
Would
X === 1 or Y === 1
And
X !== 3 && Y !== 3
Be the logical opposites respectively? How can I approach re-writing these expressions so that they would evaluate to their opposite result every time?
I cannot simply do !(If X !== 1 && Y !==1) in this situation. Would De Morgan's law be applicable to what I am trying to do? I'm considering just flipping all "===" to "!===" (and vice versa) and flipping all "ands/ors" so that I can get the results I want. This seems to work in cases I've tried, however I am not sure whether it would be working in "all" cases. Thank you!
if I follow what you're asking the inverse of
If X !== 1 && Y !==1
is:
if (X == 1 || Y == 1)
which is the same as:
if !(X !== 1 && Y !==1)
Here's how to think about it: In your example, both X and Y must not equal 1 to be true; therefore if either X or Y equal 1 the statement is false. Now convert that last sentence to boolean.
When inverting a logical statement, invert the arguments and the logical condition: "and" becomes an "or" and vise-versa.
If the goal is to negate the whole condition, the simplest way to do it is to just wrap the entire expression in !.
For example the following conditional clause:
If X !== 1 && Y !== 1
can be flipped by replacing it with:
If !(X !== 1 && Y !== 1)
Now, this is perfectly correct, but it may seem rather ugly to you. This is where DeMorgan's laws can be applied, to rewrite the expression in an equivalent, but possibly syntactically simpler form.
DeMorgan's laws state that:
!(x && y) === !x || !y, and that
!(x || y) === !x && !y.
So we can for example take our ugly (but correctly flipped) conditional clause above:
If !(X !== 1 && Y !== 1)
and use the first of DeMorgan's laws listed above to rewrite it (without changing the meaning at all):
If !(X !== 1) || !(Y !== 1)
and then by simple reasoning (!(a !== b) is equivalent to !(!(a === b)) is equivalent to a === b):
If X === 1 || Y === 1
and this is (also) a flipped version of the original clause If X !== 1 && Y !== 1.

Understanding precedence of assignment and logical operator in Ruby

I can't understand precedence of Ruby operators in a following example:
x = 1 && y = 2
Since && has higher precedence than =, my understanding is that similarly to + and * operators:
1 + 2 * 3 + 4
which is resolved as
1 + (2 * 3) + 4
it should be equal to:
x = (1 && y) = 2
However, all Ruby sources (including internal syntax parser Ripper) parse this as
x = (1 && (y = 2))
Why?
EDIT [08.01.2016]
Let's focus on a subexpression: 1 && y = 2
According to precedence rules, we should try to parse it as:
(1 && y) = 2
which doesn't make sense because = requires a specific LHS (variable, constant, [] array item etc). But since (1 && y) is a correct expression, how should the parser deal with it?
I've tried consulting with Ruby's parse.y, but it's so spaghetti-like that I can't understand specific rules for assignment.
Simple. Ruby only interprets it in a way that makes sense. = is assignment. In your expectation:
x = (1 && y) = 2
it does not make sense to assign something to 1 && y. You can only assign something to a variable or a constant.
And note that the purpose of the precedence rule is to disambiguate an otherwise ambiguous expression. If one way to interpret it does not make sense, then there is no need for disambiguation, and hence the precedence rule would not be in effect.
My understanding is that in the case of
x = 1 && y = 2
The logical AND is parsed first. The AND then is forced to evaluate its left side and its right side. In the evaluation the left side the first assignment occurs, and then in the evaluation of the right side the second does the same. It is for this reason that in the case of:
x = false && y = 2
"y" will never be assigned. The AND is hit, forcing the x assignment to evaluate, but never bothering to run the y assignment, as it is unnecessary for the AND to fulfill its purpose.
In other words, the parser is, again, simply to my understanding, smart enough to recognize that in running the AND the equation is split into a left and right side (equations), which are in turn evaluated according to the order of operation.

Why does `x =! 5` return false?

I've been studying operator precedence and it was explained to me that x =! 5 returns false. I can't seem to explain why to myself again. I know =! isn't a operator so then x and 5 remain. So does that mean Ruby doesn't know what to do? If so ruby should return an error because x can have no value? Does Ruby stop at the operator and then assign a value of false to x?
x =! 5
=> false
This is because x =! 5 is being interpreted as x = (!5) (! has higer precedence than =). In Ruby every object is true except nil and false. 5 has truthy value which you are negating using the operator !. So false as result is being assigned to the local variable x.
! Called Logical NOT Operator - is used to reverse the logical state of its operand. If a condition is true, then Logical NOT operator will make false.
There's no such a thing as =! operator in Ruby. != is what checks for not equal.
So basically, when the parser is looking at the code and find an =, it looks for other operators that start with = such as ==. If it finds no match, which is the case here ( =! ), it considers the expression as an assignment, and assigns the right hand side to the left hand side. In this case, the right hand side of the = is ! 5, which is equal to false.

"Ruby-esque" if else conditional statements

I'm currently reading The Ruby Programming Language, and I am not sure how to read Ruby-esque if else statements properly. Can you help me write the ruby code below in the second code block in regular if-else statements like this?
if some_condition
return x
else
return y
end
So the ruby codes I am unsure of are these.
minimum = if x < y then x else y end
max = x > y ? x : y
Thank you!
Both of the forms you seem to be having difficulty with make use of an idea Ruby takes from the Functional Programming paradigm: namely, Everything is an expression, and therefore returns a value. This is even true for conditional statements, an idea that languages like Java don't really support (for example:
public boolean test() {
boolean x = if (1 > 2 ) { false; } else { true; };
return x;
}
simply isn't syntactically valid).
You can see this in a Ruby terminal:
will_be_assigned_nil = false if (1 > 2) # => nil
will_be_assigned_nil # => nil
So, to your question.
The first one can be rewritten like this:
if x < y
mininum = x
else
minimum = y
end
The second is like the ternary operator in other languages, and is equivalent to:
if x > y
max = x
else
max = y
end
It's helpful to remember the roots & heritage of languages when trying to understand their constructs. Ruby shares the "More Than One Way To Do It" philosophy with Perl, and idiomatic Ruby code often has a high emphasis on elegance.
The "post-expression"-style conditionals are a good example of this. If I have guard expressions at the start of my methods, it's not uncommon for me to write:
raise "Pre-condition x not met" unless x # (or "if !x" , preference thing)
raise "Pre-condition y not met" unless y # etc., etc.
instead of
if !x
raise "Pre-condition x not met"
end
if !y
raise "Pre-condition y not met"
end

Resources