Comparison in Xojo: is vs equals

from MBS Xojo blog:

In Xojo you have two ways to compare objects. You can use equals operators or the is operator. Let us show you when to use “is” instead of equals “=”.

The “is” keyword will compare the internal reference value, the pointer to the memory used for the object. This avoids calling any compare operator and is usually faster. If there is no compare operator, the same compare code as for = runs.

If you use the equals sign (or <, <=, >, >= or <>), Xojo will decide whether to call the operator_compare method on the class, if it offers one. But even if the class has such an operator, a compare to a hard coded nil will just do the pointer comparison. Be aware that Xojo looks on the type of variable you use. If you use object for a variable type, the operator isn’t called.

When the second object to compare is a variable (or property or function result), the code is different. It first compares whether the first object is nil. If it is not nil, you get a call of the Operator_Compare method if it exists. If it is nil, the second object is. If you ever write an Operator_Compare yourself, please be aware that the other object may be nil.

There is an edge case I found: If both sides are constant nil, the Xojo compiler doesn’t know what to do and inserts a VariantCompare call to check if both are equal. I would have expected that it would do a ptr compare for both sides being nil.

If you use variant for the variable type, things are a bit different for equals. If the variant contains nil, it now raises an NilObjectException if it tries to convert the value to the other one and needs to convert to a specific class. If both sides are variant, Xojo runs Operator_Compare again and may even run it on the second value and pass the first as parameter.

Sounds complicated, right?

Just remember: If you compare two values for whether they point to the same object, please use “is” to compare pointers. Other ways just use the normal operators to compare. This will help with objects like Date and DateTime, which have an Operator_Compare to compare values instead of pointers.

And to show some details, here some example code:

Dim d1 As New DateTime(2023, 10, 10) // <- older
Dim d2 As New DateTime(2024, 10, 10)
Dim d3 As New DateTime(2024, 10, 10)
Dim d4 As DateTime = d3

Dim r1 As Boolean = d3 = d4  // true,  same object
Dim r2 As Boolean = d3 Is d4 // true,  same object
Dim r3 As Boolean = d2 = d3  // true,  same values, using Compare_Operator
Dim r4 As Boolean = d2 Is d3 // false, not the same object
Dim r5 As Boolean = d1 = d2  // false, different values, using Compare_Operator
Dim r6 As Boolean = d1 < d2  // true,  value of d1 is smaller

// object doesn't call Compare_Operator
Dim o1 As Object = d1
Dim o2 As Object = d2
Dim o3 As Object = d3
Dim o4 As Object = d4

Dim r7 As Boolean = o1 = o2 // false, different pointers, but Compare_Operator not run!
Dim r8 As Boolean = o2 = o3 // false, different pointers, but Compare_Operator not run!
Dim r9 As Boolean = o3 = o4 // true, same pointer
Dim r0 As Boolean = o2 < o3 // true, usually d2 gets lower pointer value!

// variant behaves like DateTime above
Dim v1 As Variant = d1
Dim v2 As Variant = d2
Dim v3 As Variant = d3
Dim v4 As Variant = d4

Dim s1 As Boolean = v3 = v4  // true,  same object
Dim s2 As Boolean = v3 Is v4 // true,  same object
Dim s3 As Boolean = v2 = v3  // true,  same values, using Compare_Operator
Dim s4 As Boolean = v2 Is v3 // false, not the same object
Dim s5 As Boolean = v1 = v2  // false, different values, using Compare_Operator
Dim s6 As Boolean = v1 < v2  // true,  pointer value of d1 is smaller

We hope you learnt something and if you have questions, please don’t hesitate to contact us.

9 Likes