Difference between "not" and "!" in ruby - 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

Related

Why does Ruby have no !== operator?

Is all equality in Ruby is "strict", analogous to === in PHP? I notice that there is a === operator in Ruby but it does something different.
=== is not an equality operator!
Not.
But, what is it?
You might be familiar with === as an equality operator in Javascript and PHP, but this just not an equality operator in Ruby and has fundamentally different semantics from other languages.
So what does === do?
=== is the pattern matching operator!
=== matches regular expressions
=== checks range membership
=== checks being instance of a class
=== calls lambda expressions
=== sometimes checks equality, but mostly it does not
So how does this madness make sense?
Enumerable#grep uses === internally
case when statements use === internally
That is why you can use regular expressions and classes and ranges and even lambda expressions in a case when statement.
Some examples
case value
when /regexp/
# value matches this regexp
when 4..10
# value is in range
when MyClass
# value is an instance of class
when ->(value) { ... }
# lambda expression returns true
when a, b, c
# value matches one of a, b, c with `===`
when *array
# value matches an element in array with `===`
when x
# values is equal to x unless x is one of the above
end
All these example work with pattern === value too, as well as with grep method.
I can only guess why there's no !== method but Tadman's intuition seems spot on, === is mostly used indirectly through case when and grep and thus likely didn't seem to need an explicit inverse operator. Most style guides for production code ban the use of === operator anyway.
If you are looking for other equality operators, check .eql? and .equal?
Ruby doesn't need a strict ===-type operator because the default comparator == is already quite strict, unlike PHP and others. It's not often the case any sort of conversion is done, so the cases where it is performed stand out as exceptional:
0 == ""
# => false
0 == "0"
# => false
"" == " "
# => false
0 == nil
# => false
0 == 0.0
# => true
In fact when you do use === you're often asking for trouble by being overly specific or inviting unexpected behaviour:
"" === String
# => false
String === ""
# => true
String === Object
# => false
Object === String
# => false
The meaning of === is defined by various classes in different ways to mean things often unrelated to "equality". It's just a shorthand like << is at times. Object === String is actually Object.===(String) which is why it produces different results from String.===(Object). In that case it means "is equal to or a derived class of...".
It's because of this relative rarity that !== doesn't really need to exist in the first place. === is often used only indirectly, as it's the default method for comparing things via a case statement.
Ah... after digging deeper I think I answered my own question. Ruby has .eql? .equal? link
Ruby's equality is not strict using ==, at least not like === in JavaScript. Ruby has stricter equality methods, such as eql? and equal?, but the === is not for strict equality. The === method is called the subsumption operator. It's most used implicitly in case statements. This is to say that
case a
when b ...
when c ...
else ...
end
is equivalent to
if b === a
...
elsif c === a
...
else
...
end
Having said that, !== could exist, but instead it is just left for the user to do !(a === b). Note that === is not commutative as in a === b is not the same as b === a.

`and` is the same as `&&` but why does `and` have lower precedence?

In ruby, and is the same as &&, but why does and have lower precedence?
false and false || true # => false
false && false || true # => true
You're absolutely correct that the humanised operators have lower precedence. There is an excellent (and brief!) article on this here if you want more information.
Simplest answer (from that article):
Properly understood, and and or are control flow operators, not boolean operators.

Why does 1 === (1..12) evaluate to false, while (1..12) === 1 evaluates to true? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
=== vs. == in Ruby
I've seen it used a few times lately but can't figure out what it does. Can anyone illustrate how it works?
Just like with every other method in Ruby (or actually pretty much any object-oriented language),
a === b
means whatever the author of a's class wants it to mean.
However, if you don't want to confuse the heck out of your colleagues, the convention is that === is the case subsumption operator. Basically, it's a boolean operator which asks the question "If I have a drawer labelled a would it make sense to put b in that drawer?"
An alternative formulation is "If a described a set, would b be a member of that set?"
For example:
(1..5) === 3 # => true
(1..5) === 6 # => false
Integer === 42 # => true
Integer === 'fourtytwo' # => false
/ell/ === 'Hello' # => true
/ell/ === 'Foobar' # => false
The main usage for the === operator is in case expressions, since
case foo
when bar
baz
when quux
flurb
else
blarf
end
gets translated to something (roughly) like
_temp = foo
if bar === _temp
baz
elsif quux === _temp
flurb
else
blarf
end
Note that if you want to search for this operator, it is usually called the triple equals operator or threequals operator or case equality operator. I really dislike those names, because this operator has absolutely nothing whatsoever to do with equality.
In particular, one would expect equality to be symmetric: if a is equal to b, then b better be also equal to a. Also, one would expect equality to be transitive: if a == b and b == c, then a == c. While there is no way to actually guarantee that in a single-dispatch language like Ruby, you should at least make an effort to preserve this property (for example, by following the coerce protocol).
However, for === there is no expectation of either symmetry or transitivity. In fact, it is very much by design not symmetric. That's why I don't like calling it anything that even remotely resembles equality. It's also why I think, it should have been called something else like ~~~ or whatever.
Thanks for your edit Jacob, I was about to call you out ;) I'll post a couple of examples anyway. The implementation of === differs depending on type. For example:
(1...3) === 2
=> true
/test/ === "this is a test"
=> true
case 'test'
when /blah/
"Blach"
when /test/
"Test"
else
"Fail"
end
=> "Test"
Stephen, checkout http://ruby-doc.org/docs/ProgrammingRuby/ (the "Pickaxe"), it should be able to help you out with questions such as this in the future.
In Ruby, the === operator is used to test equality within a when clause of a case statement. In other languages, the above is true.
To my knowledge, Ruby doesn't have true operators, they are all methods which are invoked on the LHS of the expression, passing in the RHS of the expression.
So, really, you could override any "operator" you want in your classes to perform whatever the heck you want (analogous to operator overloading in C++).

Why does Ruby use =~ instead of ~= for matching operator?

I have this stupid question about matching operator in Ruby. Why did Ruby make the matching operator =~ instead of ~=? Is there a historical, psychological or other considerations of making the former instead of the later?
I couldn't found any info on this, and I need to make sense about this because I keep typing the wrong thing due to other operator such as +=, -=, !=, >= and <= place the = on the right of the other operator, while =~ is the opposite.
Please enlight me.
My opinion is that it is more consistant. They are several 'equal' and 'match' operators. For instance:
=~ for 'matches'
!~ for 'does not match'
== for 'equals'
!= for 'does not equal'
Also from a far higher level prospective if you think about the way you would read these symbols in words it makes prefect sense:
+= -= are basically saying a = a + b or a = a - b obviously the
addition(+) or subtraction(-) must happen prior to the
assignment(=).
As for comparison operators like >= != these make sense too because
you are asking is a greater than(>) or equal to(=) bor does
a not(!) equal(=) b so why not write it that way.
In the same way ~= would be like saying does a pattern(~)
match(=) b when what you want is =~ which would read does a
match(=) pattern(~) b.
If you read them as words it become fairly succinct.

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

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

Resources