Menu

#376 \'OrderedCollection\' setlike methods

3.2.0
closed
Classes (182)
5
2012-08-14
2007-08-06
No

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.)

Discussion

  • Rick McGuire

    Rick McGuire - 2007-08-06

    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.

     
  • Rony G. Flatscher

    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"?

     

Anonymous
Anonymous

Add attachments
Cancel