The setlike methods 'difference', 'interSection', 'subSet', 'union', and
'xor' yield wrong results, if the argument 'other' is of type 'MapCollection'.
Example with 'subSet':
----------- cut here -------------
t=.table~new
t[11]="eleven"
t[22]="twenty-two"
a=.array~of(11)
say "a~subset(t):" a~subset(t) / yields: 0 /
----------- cut here -------------
The reason is that the current implementation uses 'allItems' from
'other', and if 'other' is a 'Collection', then no 'makeArray' message
is sent to it and then processed.
The respective code sections could be simplified in the course of fixing
this.
(I could take over this item.)
Anonymous
Logged In: YES
user_id=1125291
Originator: NO
This is the way the ordered set methods are defined. Since only the items are meaningful for the ordered collections, the set operations are performed between the items of the target and the argument collection.
Logged In: YES
user_id=662126
Originator: YES
The problem is at first sight a little bit subtle as the current code does not use the result of "makeArray", only if "other" is not (!) a collection.
Here's the current implementation of the "OrderedCollection" "subSet" method:
--------------- cut here ---------------
/******/
/ SUBSET method /
/********/
::METHOD 'subSet' -- ordered_subset -- do we have a subset?
use strict arg other
signal on nomethod -- trap unknown method calls
if \other~isA(.Collection) then do -- if not a collection, then ask for an
other = other~makearray -- array value and use that as the iterator
end
object = self~copy -- get a reference copy
do item over other~allItems -- loop over the other collection
object~removeItem(item) -- remove from the reference
end
return 0=object~items -- if nothing left -> proper subset
nomethod:
-- an unknown method is an argument problem. report it as such.
raise syntax 93.948 array(1, "Collection")
--------------- cut here ---------------
Thanks to all of your improvements in the area of collections it is now sufficient to work with the result of the "makeArray" message. Hence the above code can be replaced with the following (actually now simpler) version:
--------------- cut here ---------------
/******/
/ SUBSET method /
/********/
::METHOD 'subSet' -- ordered_subset -- do we have a subset?
use strict arg other
signal on nomethod -- trap unknown method calls
object = self~copy -- get a reference copy
do item over other -- loop over the other collection
object~removeItem(item) -- remove from the reference
end
return 0=object~items -- if nothing left -> proper subset
nomethod:
-- an unknown method is an argument problem. report it as such.
raise syntax 93.948 array(1, "Collection")
--------------- cut here ---------------
As DO item OVER other will send the "makeArray" message to "other", the appropriate array object will be returned by the receiving collection, depending on the collection class it belongs to.
The same would be true for all the other methods (including "appendAll", which I missed in my first posting): remove all tests whether "other" is of type "Collection", replace all "other~allItems" with "other~makeArray".
However, there is one thing which needs to be clarified: should it be allowed to pass a supplier object (does not possess a "makeArray" method) as "other", even if the receiver is not of type "Relation"?