How does Integer === 3 work?
Integer
is a class, which (at least in Ruby) means that it is just a boring old normal object like any other object, which just happens to be an instance of the Class
class (instead of, say, Object
or String
or MyWhateverFoo
).
Class
in turn is a subclass of Module
(although arguably it shouldn't be, because it violates the Liskov Substition Principle, but that is a discussion for another forum, and is also a dead horse that has already been beaten many many times). And in Module#===
you will find the definition you are looking for, which Class
inherits from Module
and instances of Class
(like Integer
) understand.
Module#===
is basically defined symmetric to Object#kind_of?
, it returns true
if its argument is an instance of itself. So, 3
is an instance of Integer
, therefore Integer === 3
returns true
, just as 3.kind_of?(Integer)
would.
So as I understand it, the
===
operator tests to see if the RHS object is a member of the LHS object.
Not necessarily. ===
is a method, just like any other method. It does whatever I want it to do. And in some cases the "is member of" analogy breaks down. In this case it is already pretty hard to swallow. If you are a hardcore type theory freak, then viewing a type as a set and instances of that type as members of a set is totally natural. And of course for Array
and Hash
the definition of "member" is also obvious.
But what about Regexp
? Again, if you are formal languages buff and know your Chomsky backwards, then interpreting a Regexp
as an infinite set of words and String
s as members of that set feels completely natural, but if not, then it sounds kind of weird.
So far, I have failed to come up with a concise description of precisely what ===
means. In fact, I haven't even come up with a good name for it. It is usually called the triple equals operator, threequals operator or case equality operator, but I strongly dislike those names, because it has absolutely nothing to do with equality.
So, what does it do? The best I have come up with is: imagine you are making a table, and one of the column headers is Integer
. Would it make sense to write 3
in that column? If one of the column headers is /ab*a/
, would it make sense to write 'abbbba'
in that column?
Based on that definition, it could be called the subsumption operator, but that's even worse than the other examples ...
How do the PHP equality (== double equals) and identity (=== triple equals) comparison operators differ?
Difference between ==
and ===
The difference between the loosely ==
equal operator and the strict ===
identical operator is exactly explained in the manual:
Comparison Operators
Example | Name | Result |
---|---|---|
$a == $b | Equal | TRUE if $a is equal to $b after type juggling. |
$a === $b | Identical | TRUE if $a is equal to $b, and they are of the same type. |
Java: Integer equals vs. ==
The JVM is caching Integer values. Hence the comparison with ==
only works for numbers between -128 and 127.
Refer: #Immutable_Objects_.2F_Wrapper_Class_Caching
Which equals operator (== vs ===) should be used in JavaScript comparisons?
The strict equality operator (===
) behaves identically to the abstract equality operator (==
) except no type conversion is done, and the types must be the same to be considered equal.
Reference: Javascript Tutorial: Comparison Operators
The ==
operator will compare for equality after doing any necessary type conversions. The ===
operator will not do the conversion, so if two values are not the same type ===
will simply return false
. Both are equally quick.
To quote Douglas Crockford's excellent JavaScript: The Good Parts,
JavaScript has two sets of equality operators:
===
and!==
, and their evil twins==
and!=
. The good ones work the way you would expect. If the two operands are of the same type and have the same value, then===
producestrue
and!==
producesfalse
. The evil twins do the right thing when the operands are of the same type, but if they are of different types, they attempt to coerce the values. the rules by which they do that are complicated and unmemorable. These are some of the interesting cases:'' == '0' // false
0 == '' // true
0 == '0' // true
false == 'false' // false
false == '0' // true
false == undefined // false
false == null // false
null == undefined // true
' \t\r\n ' == 0 // true
The lack of transitivity is alarming. My advice is to never use the evil twins. Instead, always use
===
and!==
. All of the comparisons just shown producefalse
with the===
operator.
Update:
A good point was brought up by @Casebash in the comments and in @Phillipe Laybaert's answer concerning objects. For objects, ==
and ===
act consistently with one another (except in a special case).
var a = [1,2,3];
var b = [1,2,3];
var c = { x: 1, y: 2 };
var d = { x: 1, y: 2 };
var e = "text";
var f = "te" + "xt";
a == b // false
a === b // false
c == d // false
c === d // false
e == f // true
e === f // true
The special case is when you compare a primitive with an object that evaluates to the same primitive, due to its toString
or valueOf
method. For example, consider the comparison of a string primitive with a string object created using the String
constructor.
"abc" == new String("abc") // true
"abc" === new String("abc") // false
Here the ==
operator is checking the values of the two objects and returning true
, but the ===
is seeing that they're not the same type and returning false
. Which one is correct? That really depends on what you're trying to compare. My advice is to bypass the question entirely and just don't use the String
constructor to create string objects from string literals.
Reference
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3
What does the += operator do in Java?
The "common knowledge" of programming is that x += y
is an equivalent shorthand notation of x = x + y
. As long as x
and y
are of the same type (for example, both are int
s), you may consider the two statements equivalent.
However, in Java, x += y
is not identical to x = x + y
in general.
If x
and y
are of different types, the behavior of the two statements differs due to the rules of the language. For example, let's have x == 0
(int) and y == 1.1
(double):
int x = 0;
x += 1.1; // just fine; hidden cast, x == 1 after assignment
x = x + 1.1; // won't compile! 'cannot convert from double to int'
+=
performs an implicit cast, whereas for +
you need to explicitly cast the second operand, otherwise you'd get a compiler error.
Quote from Joshua Bloch's Java Puzzlers:
(...) compound assignment expressions automatically cast the result of
the computation they perform to the type of the variable on their
left-hand side. If the type of the result is identical to the type of
the variable, the cast has no effect. If, however, the type of the
result is wider than that of the variable, the compound
assignment operator performs a silent narrowing primitive
conversion [JLS 5.1.3].
Why Java does not see that Integers are equal?
Check out this article: Boxed values and equality
When comparing wrapper types such as Integer
s, Long
s or Boolean
s using ==
or !=
, you're comparing them as references, not as values.
If two variables point at different objects, they will not ==
each other, even if the objects represent the same value.
Example: Comparing different Integer objects using
==
and!=
.Integer i = new Integer(10);
Integer j = new Integer(10);
System.out.println(i == j); // false
System.out.println(i != j); // true
The solution is to compare the values using .equals()
…
Example: Compare objects using
.equals(…)
Integer i = new Integer(10);
Integer j = new Integer(10);
System.out.println(i.equals(j)); // true
…or to unbox the operands explicitly.
Example: Force unboxing by casting:
Integer i = new Integer(10);
Integer j = new Integer(10);
System.out.println((int) i == (int) j); // true
References / further reading
- Java: Boxed values and equality
- Java: Primitives vs Objects and References
- Java: Wrapper Types
- Java: Autoboxing and unboxing
How does integer-float comparison work?
Ruby used to convert bignums to floats in such comparisons, and in the conversion precision was lost. The issue is solved in more recent versions.
How does adding String with Integer work in JavaScript?
"" + 1 === "1"
"1" + 10 === "110"
"110" + 2 === "1102"
"1102" - 5 === 1097
1097 + "8" === "10978"
In JavaScript, the +
operator is used for both numeric addition and string concatenation. When you "add" a number to a string the interpreter converts your number to a string and concatenates both together.
When you use the -
operator, however, the string is converted back into a number so that numeric subtraction may occur.
When you then "add" a string "8"
, string concatenation occurs again. The number 1097
is converted into the string "1097"
, and then joined with "8"
.
Is there a difference between == and is?
is
will return True
if two variables point to the same object (in memory), ==
if the objects referred to by the variables are equal.
>>> a = [1, 2, 3]
>>> b = a
>>> b is a
True
>>> b == a
True
# Make a new copy of list `a` via the slice operator,
# and assign it to variable `b`
>>> b = a[:]
>>> b is a
False
>>> b == a
True
In your case, the second test only works because Python caches small integer objects, which is an implementation detail. For larger integers, this does not work:
>>> 1000 is 10**3
False
>>> 1000 == 10**3
True
The same holds true for string literals:
>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True
Please see this question as well.
Related Topics
Using the Right Exception Subclass in Ruby
Openssl Causing Very Slow Rails Boot Time on Windows
Conditional Dependency in Ruby Gemspec
What Does "String Literal in Condition" Mean
How to Get the Real File from S3 Using Carrierwave
Rewrite Template.Js.Erb into Template.Js.Slim
Differencebetween a Constant and a Variable in Ruby
Why Rails Can Use 'If' as Hash Key But Not in Ruby
Is /Etc/Irbrc Installed by Os X? Does Irb Read It
Ruby Code for Modifying Outer Quotes on Strings
Official Expansion of ||= Conditional Assignment Operator
Iterate Through Array of Hashes in Ruby
How to Set the Mechanize Page Encoding
How to Fix in Ruby on Rails the Undefined Method 'Alias_Method_Chain' Error
Bundle Install Is Using a Different Ruby Version
Make User-Inputted Url into External Link in Rails