Perl Modules for Array/Set Handling

### Purpose

To cross-check a personal selection of modules which offer:

Array and Set modules | Method lists
" | Overloaded methods

Module names are read from data/module.list.ini, which is shipped with the distro.
Each module's data has an indicator - 'include = Yes/No' - which makes it easy to edit & re-run.
Further, each module has an indicator - 'overload_type = 1/2/3' - to specify the syntax to look for when processing overloads.
Per-module notes are handled using the same mechanism.
Excluded modules are listed at the end of this report.

### Report generator

Module | Version
Benchmark::Featureset::SetOps | 1.04

### Modules included

Name | Version | Method count | Notes
1: Array::AsObject | 1.02 | 41 | Depends indirectly on Date::Manip
2: Object::Array | 0.060 | 18 | Doesn't really offer set operations
3: Set::Array | 0.30 | 47 | Some methods, e.g. difference(), update the invocant unexpectedly
4: Set::Bag | 1.012 | 17 | Supports multisets, so new() takes a hash, and elements are (name, value) pairs
5: Set::Light | 0.04 | 6 | Claims to be very small and fast compared to Set::Object and Set::Scalar
6: Set::Object | 1.35 | 39 | Requires a C compiler. Second choice after Set::Tiny
7: Set::Scalar | 1.29 | 44 | Long term unfixed bug in Set::Scalar::ValuedUniverse
8: Set::SortedArray | 0.02 | 21 | Modification of the set (i.e. after creation) is not supported
9: Set::Tiny | 0.03 | 24 | Recommended, taking in to account features (+), unfixed bugs (-), minimal dependencies (+) and, lastly, speed (+). Stats below
10: Set::Toolkit | 0.11 | 16 | Bug report of random test failures
Name | Version | Method count | Notes

Method names are found by scanning the source for /^sub.../.
Method names starting with '_' are ignored.
Also ignored are indented subs as in Set::Toolkit::TieArray, which is within the source of Set::Toolkit.
Sub-class files for Object::Array and Set::Scalar have been scanned and included.
Scanning the source means modules must be installed, but no attempt is made to load them at run-time.
Source files are found by running 'mwhere' which is shipped with the marvellous App::moduleswhere.
Version numbers are found by running 'mversion' which is shipped with the marvellous Module::Version.

### Methods

Method | Array::AsObject | Object::Array | Set::Array | Set::Bag | Set::Light | Set::Object | Set::Scalar | Set::SortedArray | Set::Tiny | Set::Toolkit
1: AUTOLOAD |  |  |  |  |  | Yes |  |  |  |
2: DESTROY |  |  |  |  |  |  | Yes |  |  |
3: ELEMENT_SEPARATOR |  |  |  |  |  |  | Yes |  |  |
4: SET_FORMAT |  |  |  |  |  |  | Yes |  |  |
5: STORABLE_freeze |  |  |  |  |  | Yes |  |  |  |
6: STORABLE_thaw |  |  |  |  |  | Yes |  |  |  |
7: append |  |  | Yes |  |  |  |  |  |  |
8: are_equal |  |  |  |  |  |  | Yes. eq |  |  |
9: as_array |  |  |  |  |  |  |  |  |  | Yes. @{}
10: as_hash | Yes |  | Yes |  |  |  |  |  |  |
11: as_string |  |  |  |  |  | Yes. "" | Yes. "" | Yes | Yes | Yes. ""
12: as_string_callback |  |  |  |  |  | Yes | Yes | Yes |  |
13: asymmetric_difference |  |  |  |  |  |  |  | Yes |  |
14: at | Yes |  | Yes |  |  |  |  |  |  |
15: bag |  |  | Yes. & | Yes. "" |  |  |  |  |  |
16: binary_intersection |  |  |  |  |  |  |  | Yes. * |  |
17: cartesian_product |  |  |  |  |  |  | Yes |  |  |
18: cartesian_product_iterator |  |  |  |  |  |  | Yes |  |  |
19: clear | Yes | Yes | Yes |  |  |  | Yes |  | Yes |
20: clone |  |  |  |  |  |  | Yes |  | Yes. copy |
21: cmp |  |  |  |  |  |  | Yes |  |  |
22: compact | Yes |  | Yes |  |  |  |  |  |  |
23: compare |  |  |  |  |  | Yes | Yes. <=> | Yes |  |
24: complement |  |  | Yes | Yes. neg |  |  | Yes |  |  |
25: contains |  | Yes |  |  |  | Yes |  |  | Yes. has |
26: copy |  |  |  | Yes. = |  |  |  |  |  |
27: count | Yes |  | Yes |  |  |  |  |  |  |
28: cpop |  |  | Yes |  |  |  |  |  |  |
29: cshift |  |  | Yes |  |  |  |  |  |  |
30: delete | Yes | Yes | Yes | Yes. -= | Yes. remove | Yes | Yes |  |  |
31: delete_at | Yes |  | Yes |  |  |  |  |  |  |
32: difference | Yes |  | Yes. - | Yes. - |  | Yes. - | Yes | Yes. - | Yes |
33: duplicates |  |  | Yes |  |  |  |  |  |  |
34: each |  |  |  |  |  |  | Yes |  |  |
35: elem |  | Yes |  |  |  |  |  |  |  |
36: element |  |  |  |  |  | Yes | Yes |  | Yes. member |
37: elements |  |  |  | Yes |  | Yes | Yes |  | Yes. members | Yes
38: elems |  | Yes |  |  |  |  |  |  |  |
39: empty_clone |  |  |  |  |  |  | Yes |  |  |
40: eq |  |  |  | Yes. eq |  |  |  |  |  |
41: equal |  |  |  |  |  | Yes. == |  |  |  |
42: err | Yes |  |  |  |  |  |  |  |  |
43: errmsg | Yes |  |  |  |  |  |  |  |  |
44: exists | Yes | Yes | Yes |  | Yes. contains |  |  |  |  |
45: extend |  |  |  |  |  |  | Yes |  |  |
46: fill | Yes |  | Yes |  |  |  | Yes |  |  |
47: find |  |  |  |  |  |  |  |  |  | Yes
48: first | Yes |  | Yes |  |  |  |  |  |  | Yes
49: flatten |  |  | Yes |  |  |  |  |  |  |
50: foreach |  |  | Yes |  |  |  |  |  |  |
51: grab |  |  |  | Yes |  |  |  |  |  |
52: grep |  | Yes |  |  |  |  |  |  |  |
53: has |  |  |  |  |  | Yes | Yes |  |  |
54: have_same_universe |  |  |  |  |  |  | Yes |  |  |
55: impose |  |  | Yes |  |  |  |  |  |  |
56: index | Yes |  | Yes |  |  |  |  |  |  |
57: indices |  |  | Yes |  |  |  |  |  |  |
58: insert |  |  |  | Yes. += | Yes |  | Yes |  | Yes | Yes
59: intersection | Yes |  | Yes. * | Yes. & |  | Yes | Yes | Yes | Yes |
60: invert |  |  |  |  |  | Yes | Yes |  | Yes |
61: is_disjoint |  |  |  |  |  | Yes | Yes. != | Yes. != | Yes |
62: is_empty | Yes |  | Yes |  | Yes. is_null |  |  |  |  | Yes
63: is_equal | Yes |  | Yes. == |  |  |  | Yes. == | Yes. == | Yes |
64: is_key |  |  |  |  |  | Yes |  |  |  |
65: is_null |  |  |  |  |  |  | Yes |  | Yes. is_empty |
66: is_ordered |  |  |  |  |  |  |  |  |  | Yes
67: is_proper_subset |  |  |  |  |  |  | Yes. < | Yes. < | Yes |
68: is_proper_superset |  |  |  |  |  |  | Yes. > | Yes. > | Yes |
69: is_properly_intersecting |  |  |  |  |  |  | Yes |  | Yes |
70: is_subset | Yes |  |  |  |  |  | Yes. <= | Yes. <= | Yes |
71: is_superset |  |  |  |  |  |  | Yes. >= | Yes. >= | Yes |
72: is_unique |  |  |  |  |  |  |  |  |  | Yes
73: is_universal |  |  |  |  |  |  | Yes |  |  |
74: isa |  | Yes |  |  |  |  |  |  |  |
75: ish_int |  |  |  |  |  | Yes |  |  |  |
76: join |  | Yes | Yes |  |  |  |  |  |  |
77: last | Yes |  | Yes |  |  |  |  |  |  | Yes
78: length | Yes |  | Yes |  |  |  |  |  |  |
79: list | Yes |  |  |  |  |  |  |  |  |
80: map |  | Yes |  |  |  |  |  |  |  |
81: max | Yes |  | Yes |  |  |  |  |  |  |
82: maximize |  |  |  | Yes. |= |  |  |  |  |  |
83: member |  |  |  |  |  | Yes |  |  |  |
84: members |  |  |  |  |  |  |  | Yes |  |
85: merge |  |  |  |  |  |  |  | Yes. + |  |
86: min | Yes |  |  |  |  |  |  |  |  |
87: minimize |  |  |  | Yes. &= |  |  |  |  |  |
88: ne |  |  |  | Yes. ne |  |  |  |  |  |
89: new | Yes | Yes | Yes | Yes | Yes |  | Yes | Yes | Yes | Yes
90: new_presorted |  |  |  |  |  |  |  | Yes |  |
91: not_equal | Yes |  | Yes. != |  |  | Yes. != |  |  |  |
92: not_subset | Yes |  |  |  |  |  |  |  |  |
93: null |  |  |  |  |  |  | Yes |  |  |
94: op_intersection |  |  |  |  |  | Yes. * |  |  |  |
95: op_invert |  |  |  |  |  | Yes. / |  |  |  |
96: op_symm_diff |  |  |  |  |  | Yes. % |  |  |  |
97: op_union |  |  |  |  |  | Yes. + |  |  |  |
98: ordered_elements |  |  |  |  |  |  |  |  |  | Yes
99: over_delete |  |  |  | Yes |  |  |  |  |  |
100: pack |  |  | Yes |  |  |  |  |  |  |
101: pop | Yes | Yes | Yes. >>= |  |  |  |  |  |  |
102: power_set |  |  |  |  |  |  | Yes |  |  |
103: power_set_iterator |  |  |  |  |  |  | Yes |  |  |
104: print |  |  | Yes |  |  |  |  |  |  |
105: proper_subset |  |  |  |  |  | Yes. < |  |  |  |
106: proper_superset |  |  |  |  |  | Yes. > |  |  |  |
107: push | Yes | Yes | Yes. << |  |  |  |  |  |  |
108: randomize | Yes |  | Yes |  |  |  |  |  |  |
109: remove |  |  |  |  |  |  |  |  | Yes. delete | Yes
110: reverse | Yes |  | Yes |  |  |  |  |  |  |
111: rindex | Yes |  | Yes |  |  |  |  |  |  |
112: rotate | Yes |  | Yes |  |  |  |  |  |  |
113: search |  |  |  |  |  |  |  |  |  | Yes
114: set | Yes |  | Yes |  |  | Yes |  |  | Yes |
115: shift | Yes | Yes | Yes. >> |  |  |  |  |  |  |
116: size |  | Yes |  |  | Yes |  | Yes. bool | Yes | Yes | Yes
117: slice |  | Yes |  |  |  |  |  |  |  |
118: sort | Yes |  | Yes |  |  |  |  |  |  |
119: splice | Yes | Yes | Yes |  |  |  |  |  |  |
120: strengthen |  |  |  |  |  | Yes |  |  |  |
121: strong_pkg |  |  |  |  |  | Yes |  |  |  |
122: subset |  |  |  |  |  | Yes. <= |  |  |  |
123: sum |  |  |  | Yes. + |  |  |  |  |  |
124: superset |  |  |  |  |  | Yes. >= |  |  |  |
125: symmetric_difference | Yes |  | Yes. % |  |  | Yes | Yes | Yes. % | Yes. unique |
126: tie_array_pkg |  |  |  |  |  | Yes |  |  |  |
127: tie_hash_pkg |  |  |  |  |  | Yes |  |  |  |
128: union | Yes |  | Yes. + | Yes. | |  | Yes | Yes | Yes | Yes |
129: unique | Yes |  | Yes |  |  | Yes | Yes | Yes. / |  |
130: universe |  |  |  |  |  |  | Yes |  |  |
131: unordered_elements |  |  |  |  |  |  |  |  |  | Yes
132: unshift | Yes | Yes | Yes. <<= |  |  |  |  |  |  |
133: version | Yes |  |  |  |  |  |  |  |  |
134: weak_pkg |  |  |  |  |  | Yes |  |  |  |
135: weak_set |  |  |  |  |  | Yes |  |  |  |
136: weaken |  |  |  |  |  | Yes |  |  |  |
Method | Array::AsObject | Object::Array | Set::Array | Set::Bag | Set::Light | Set::Object | Set::Scalar | Set::SortedArray | Set::Tiny | Set::Toolkit

A cell containing 'Yes' means that module has a method of that name.
A token after 'Yes' is the overloaded operator defined in that module for that method.

Just because 2 modules have a method with the same name does not mean the subs' behaviour is identical.
For instance, symmetric_difference() in Set::Tiny and Set::Scalar return different lists.
Not only that, but Set::Tiny's method returns a set, whereas Set::Scalar's returns a string.
Further, some methods in Set::Array change the invocant object, which is an apalling design feature.
Sample code ships as scripts/symmetric.demo.pl.
As always, RTFM!

In order to make life difficult:

Object::Array fiddles a list of method names copied from List::MoreUtils.
Set::Light has 2 aliases for exists: has and contains.
Set::Object and Set::Toolkit define some overloads via subs. These are ignored.

### Modules excluded

Name | Notes
1: Array::Compare | Array::Compare has very limited (focused) functionality
2: Array::Uniq | Array::Uniq likewise
3: Array::Utils | Array::Utils likewise
4: Bit::Vector | Bit::Vector is sophisticated, but is more like an underlying support mechanism for sets and hence leaves a lot up to the end-user
5: Set::DynamicGroups | Set::DynamicGroups handles multisets, as does Set::Bag. It's designed to allow groups to be defined dynamically by rules based on other groups. It has partial support for nested groups
6: Set::Equivalence | A set of objects or scalars with no duplicates and a user-configurable equivalence relation
7: Set::Groups | Set::Groups supports nested groups, and hence a completely different set of methods
8: Set::Hash | Set::Hash allows you to create strings as objects and use OO-style methods on them. It's a sub-class of Set::Array
9: Set::NestedGroups | Set::NestedGroups is like Set::Groups
10: Set::Relation | Set::Relation is an emulator for RDBMS-style relational data
Name | Notes

### Environment

Author | Ron Savage
Date | 2015-11-16
OS | Debian V 6.0.4
Perl | 5.20.2