Has anyone given thought to - or even better yet, implemented - overriding Equals in a PABLO*? Ideally the method should be capable of dealing with objects, as well as primitives, and also data structures like temp-tables etc.
Serialisation is an option, but it's more appropriate to cloning than identity comparisons.
Some of MSDN's thoughts on the matter here ; some of IBM's here.
-- peter
* Plain ABL Object
How could equals ever be anything but type specific ... or am I getting you wrong?
tamhas wrote:
How could equals ever be anything but type specific ... or am I getting you wrong?
Equals() is instance-specific AFAIK. Of course, I may be wrong (that has occasionally happened ) but I'm still interested in a fast value equality method.
An easy way to check type equality is to use RCODE-INFO:MD5-value, incidentally.
-- peter
Just to be careful ....
Equality means:
1. Same type, i.e., class or subclass.
2. Same version of class (where your MD5 comes in)
3. Same data members. <<>>
The first two seem simple and the last one tedious. Now, if you guys would give us WRITE-XML for a class, then one could do that for both and simply compare whether the results were identical.
Baring something built-in, if one had implemented a method which would do the logical equivalent of WRITE-XML, that would seem a good way to do it.
Equality means:
1. Same type, i.e., class or subclass.
2. Same version of class (where your MD5 comes in)
3. Same data members.
I'd modify this to say "same state of object", since the existence of the members (i.e. behaviour) is covered by 1 & 2.
Also, equality can mean
4. Same instance of an object
#3 is what I'm looking for (assuming 10.2B). I can do it via serialization ("WRITE-XML") but that's potentially slow and overkill.
-- peter
What's makes you believe you know what makes two instances of my
classes 'equal'?
If it would be so easy Equal() might be defined on
Progress.Lang.Object as FINAL?
What's makes you believe you know what makes two instances of my
classes 'equal'?
I don't, of course. I'm looking for general strategies or approaches, to implement in my own classes.
There certainly are some defaults, such as objRef1 being the same as objRef2 that do satisfy some level of equality, which could be implemented in PLO, but this isn't easy to generalise, for sure.
-- peter
as well as primitives, and also data structures like temp-tables etc.
An Equals() method on primitives? Tell me more about that! Or do you mean more a static helper class than can compare two primitives or a method of a class that compares an instance to a primitive?
but this isn't easy to generalise, for sure.
Certainly that's true. I'd wish further some sort of annotations that could mark relevant data members for comparison.
One example: Two instances (of the same class) both have a (dynamic) buffer for the customer table, both pointing at the same record. The buffers handles (the actual data members, I'd say) are different values. I'd still consider both instances as equal (as equal in state or knowledge).
A too generic approach would probably return NOT equal.
Yes, I meant value, not that the same data members existed.
Same instance would be covered by same handle, no?
That seems to me to be the trivial case. Much more interesting is something being a perfect clone, but not the same object.
Performance is testable on WRITE-XML versus pair-wise comparisons ... or it would be if we had WRITE-XML. It appeals to me because it is three operations and highly standardized, i.e., WRITE-XML of other, WRITE-XML of self, compare. Pairwise comparisons have the advantage of stopping after the first mismatch. Note that every property comparison on the other object implies the equivalent of a getter method call.
Interesting possible issue, if WRITE-XML serializes state or one has a hand-coded method that serializes state, the contents of the output are not equivalent to testing all externally visible properties. The externally visible properties can include some that are computed and thus redundant and there may be internal properties which are an important part of state, which are not publically visible.
This seems to suggest that one has to test the serialization since only it is going to have all the internal state and only the internal state.
Certainly that's true. I'd wish further some sort of annotations that could
mark relevant data members for comparison.
Indeed that would help. But if you implement your own Equals() you decide this. Annotations would help with reflection (say) being used for equality checks.
I'd still consider both instances as equal (as equal in state or knowledge).
Exactly.
A too generic approach would probably return NOT equal.
Right. A extremely-generic approach might just compare buffer handle values. Which wouldn't work niceluy at all
An Equals() method on primitives? Tell me more about that! Or do you mean
more a static helper class than can compare two primitives
This one. And again, what a class considers necessary for equality depends on that class and its developers.
-- peter
Annotations, maybe, but also some logic. I.e., if one of the primary purposes of serialization is to send things across the wire, then serializing the buffer handle is obviously meaningless ... so what is one going to serialize? For a statis buffer, it might be the ROWID. For a dynamic buffer on a DB table, it might be the _File number and the ROWID. But, gosh, if it is a dynamic buffer on a temp-table which is not even contained in the object ... what in the world would one send? (btw, that is something which will be coming up in the M-S-E discussion or I might not have thought about it).
And again, what a class considers necessary for equality depends on
that class and its developers.
Amen!
Back at 2K points. Congrats, Dr. Thomas!
Out of nearly 2.5K posts, however!
Same instance would be covered by same handle, no? That seems to me to be the trivial case.
Agreed, but included for completeness' sake.
Much more interesting is something being a perfect clone, but not the same object.
Cloning and/or serialization is a completely different kettle of wax. Interesting, certainly, but different.
*For equality*, it would be nice to have an ABL property that returns a hash/crc value on a temp-table which reflects the contents of that table. Maybe a hash of the rowid's or something (just off the top of my head).
Performance is testable on WRITE-XML versus pair-wise comparisons ... or it would be if we had WRITE-XML. It appeals to me because it is three operations and highly standardized, i.e., WRITE-XML of other, WRITE-XML of self, compare. Pairwise comparisons have the advantage of stopping after the first mismatch. Note that every property comparison on the other object implies the equivalent of a getter method call.
As Mike pointed out, there's no easy (if any) way of generically determining what constitutes equality for a type. I believe that other languages use annotations for (some of) this functionality, but that's not currently available to us in the ABL today.
-- peter