Squeak
  links to this page:    
View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide
The boolean methods = and ==
Last updated at 2:09 pm UTC on 16 January 2006
What is the difference between the boolean methods #= and #==?

In any programming language it is important to distinquish between the value of an object, and the object itself. This is the difference between identity and equivalence. You might say it is the difference between who it is and what it is. For example who I am is "Bob", what I am is "a doctor".

Additionally it is necessary to distinquish between names or references to objects, and the objects themselves, so that "Bob Smith" may be referred to as "Bob Smith", "Bob", or "Mr. Smith". These are three references to the same person.

In Squeak we may have two objects:
 | objA objB |

we may assign different values to these objects:

objA := 1
objB := 2

In this case:

= answers true if they are the same object OR they are equivalent (same value of the instance variables), the definition of equivalent being one that can vary from class to class.

== answers true if the receiver and argument are the same object. This is a test for identity.

Now if we assign one object to the other as in:
objA := objB

In this case:



Another example:
| a b |
a _ 'hello, world'.
b _ a.
a == b. "<==== true"
a = b. "<==== true"
b _ a copy.
a == b. "<====  false"
a = b. "<====  true"


The above answers your vice-versa case. The case of #== being true and #= being false _could_ happen if you defined a class where #= returned false when presented with the same object. Why you would want to do that, however, I can't imagine. So the short answer is

== false and = true happens a lot.
== true and = false probably never happens in real life.

BobArning

Implementation in the image


If you look at:

Interpreter>>primitiveEquivalent

| thisObject otherObject |
otherObject _ self popStack.
thisObject _ self popStack.
self pushBool: thisObject = otherObject



This is invoked from the only one implementor of #== in the Squeak image.

ProtoObject>> ==

= anObject
"Primitive. Answer whether the receiver and the argument are the same
object (have the same object pointer). Do not redefine the
message == in any other class! Essential. No Lookup. Do not override in any subclass.

See Object documentation whatIsAPrimitive."


self primitiveFailed

The "C" code produced for the VM just checks to see if the addressof this object is = to the address of that object. If they are then of course they are the same object.

Now to answer your questions about #== true but #= false. Well you would need a broken #= to have that case. However the reverse of course can be true
  1. = is true, but of course #== can be false.

Now #= is implemented 55 times in the image and can be quite complex
 aCT
self class == aCT class ifFalse:[^false].
^rAdd = aCT rAdd and:[rMul = aCT rMul and:[
gAdd = aCT gAdd and:[gMul = aCT gMul and:[
bAdd = aCT bAdd and:[bMul = aCT bMul and:[
aAdd = aCT aAdd and:[aMul = aCT aMul]]]]]]]

If you have a bug where side effects of a message sent could alter an object, then sure you could have #== is true but #= is false because the object gets changed while checking it's state, but it's really a bug. I guess also having a high priority process alter the object well testing #= could also raise issues.

John M McIntosh

Remember!


== is implemented only once in the image. = is implemented in various classes. Don't forget to implement = in your own classes if you want to test for equality and can't rely on the method of the superclass. Otherwise you might get unexpected results.

And don't forget the hash



"Since various classes (particularly Sets and Dictionaries) rely on the property that equal objects have equal hashes, you should override hash whenever you override =. It must be true that (a = b) implies (a hash = b hash). The contrapositive and the converse will not generally hold. " From: Squeak Language and Classes Reference