In Ruby Integer === 5
returns true
. Similarly String === "karthik"
returns true
.
However, 5 === Integer
returns false
. And "karthik" === String
.
Why is the operator not commutative?
相关问题
- How to specify memcache server to Rack::Session::M
- Why am I getting a “C compiler cannot create execu
- reference to a method?
- ruby 1.9 wrong file encoding on windows
- gem cleanup shows error: Unable to uninstall bundl
相关文章
- Ruby using wrong version of openssl
- Difference between Thread#run and Thread#wakeup?
- how to call a active record named scope with a str
- “No explicit conversion of Symbol into String” for
- Segmentation fault with ruby 2.0.0p247 leading to
- How to detect if an element exists in Watir
- uninitialized constant Mysql2::Client::SECURE_CONN
- ruby - simplify string multiply concatenation
it needs to implement case-when comparisons
It's normal to have non-commutative operators.
And as it happens,
===
exists in part as the case-when operator. That's rather elaborate in Ruby, and it couldn't be so if it had to be simplified to a commutative op.One very simple reason is that the
is_a?
relationship for classes just can't be commutative. Consider the case where both operands are classes:This will return true because
String.is_a?(Class)
. HoweverString === Class
will return false, becauseClass.is_a?(String)
is false and that is of course as it should be.Another reason is that the semantics of
===
depends on its left operand. This has again two reasons: a) In ruby the semantics always depend on the left operand, because the left operand is the receiver of the method call and b) it is useful, so you can use e.g. classes, ranges and regexen in a case statement with the intended semantics.Many operators are not commutative.
The
===
is called the "case equality operator" because it is called when branching is a case.It is nice and useful that:
It would not be very useful if
Note that in Ruby 1.9, the
===
operator on a Proc/lambda will call that Proc:Again, very useful in a
case
statement, but not much in the reverse order.The simple answer is: because it doesn't make sense. The relationship the operator describes is not commutative, why should the operator be?
Just look at your own examples:
5
is anInteger
. But isInteger
a5
? What does that even mean?===
is the case subsumption operator, and subsumption doesn't commute.The fact that the case subsumption operator uses equals signs, and that it is usually called the triple equals,
threequals
orcase equality
operator is terribly unfortunate since it not only has absolutely nothing to do with equality, but it also does not conform to many of the laws that equality conforms to, such as transitivity and as you mentioned commutativity.For more of my ranting about
===
see===
operator do in Ruby?===
vs.==
in RubyInteger === 3
work?