File Coverage

blib/lib/Set/Scalar.pm
Criterion Covered Total %
statement 29 29 100.0
branch 1 2 50.0
condition n/a
subroutine 10 10 100.0
pod 0 2 0.0
total 40 43 93.0


line stmt bran cond sub pod time code
1             package Set::Scalar;
2              
3 21     21   16593 use strict;
  21         46  
  21         944  
4             # local $^W = 1;
5              
6 21     21   105 use vars qw($VERSION @ISA);
  21         33  
  21         2009  
7              
8             $VERSION = '1.29';
9             @ISA = qw(Set::Scalar::Real Set::Scalar::Null Set::Scalar::Base);
10              
11 21     21   29162 use Set::Scalar::Base qw(_make_elements is_equal as_string_callback);
  21         58  
  21         2059  
12 21     21   14000 use Set::Scalar::Real;
  21         54  
  21         7379  
13 21     21   13920 use Set::Scalar::Null;
  21         69  
  21         935  
14 21     21   12658 use Set::Scalar::Universe;
  21         50  
  21         7194  
15              
16 143     143 0 902 sub ELEMENT_SEPARATOR { " " }
17 131     131 0 456 sub SET_FORMAT { "(%s)" }
18              
19             sub _insert_hook {
20 12666     12666   16947 my $self = shift;
21              
22 12666 50       29636 if (@_) {
23 12666         15147 my $elements = shift;
24              
25 12666         39664 $self->universe->_extend( $elements );
26              
27 12666         39951 $self->_insert_elements( $elements );
28             }
29             }
30              
31             sub _new_hook {
32 6448     6448   10155 my $self = shift;
33 6448         7939 my $elements = shift;
34              
35 6448         25582 $self->{ universe } = Set::Scalar::Universe->universe;
36              
37 6448         19229 $self->_insert( { _make_elements( @$elements ) } );
38             }
39              
40             =pod
41              
42             =head1 NAME
43              
44             Set::Scalar - basic set operations
45              
46             =head1 SYNOPSIS
47              
48             use Set::Scalar;
49             $s = Set::Scalar->new;
50             $s->insert('a', 'b');
51             $s->delete('b');
52             $t = Set::Scalar->new('x', 'y', $z);
53              
54             =head1 DESCRIPTION
55              
56             =head2 Creating
57              
58             $s = Set::Scalar->new;
59             $s = Set::Scalar->new(@members);
60              
61             $t = $s->clone;
62             $t = $s->copy; # Clone of clone.
63             $t = $s->empty_clone; # Like clone() but with no members.
64              
65             =head2 Modifying
66              
67             $s->insert(@members);
68             $s->delete(@members);
69             $s->invert(@members); # Insert if hasn't, delete if has.
70              
71             $s->clear; # Removes all the elements.
72              
73             Note that clear() only releases the memory used by the set to
74             be reused by Perl; it will not reduce the overall memory use.
75              
76             =head2 Displaying
77              
78             print $s, "\n";
79              
80             The display format of a set is the members of the set separated by
81             spaces and enclosed in parentheses (), for example:
82              
83             my $s = Set::Scalar->new();
84             $s->insert("a".."e");
85             print $s, "\n";
86              
87             will output
88              
89             a b c d e
90              
91             You can even display recursive sets.
92              
93             See L for customising the set display.
94              
95             =head2 Querying
96              
97             Assuming a set C<$s>:
98              
99             @members = $s->members;
100             @elements = $s->elements; # Alias for members.
101              
102             @$s # Overloaded alias for members.
103              
104             $size = $s->size; # The number of members.
105              
106             $s->has($m) # Return true if has that member.
107             $s->contains($m) # Alias for has().
108              
109             if ($s->has($member)) { ... }
110              
111             $s->member($m) # Returns the member if has that member.
112             $s->element($m) # Alias for member.
113              
114             $s->is_null # Returns true if the set is empty.
115             $s->is_empty # Alias for is_null.
116              
117             $s->is_universal # Returns true if the set is universal.
118              
119             $s->null # The null set.
120             $s->empty # Alias for null.
121             $s->universe # The universe of the set.
122              
123             =head2 Deriving
124              
125             $u = $s->union($t);
126             $i = $s->intersection($t);
127             $d = $s->difference($t);
128             $e = $s->symmetric_difference($t);
129             $v = $s->unique($t);
130             $c = $s->complement;
131              
132             These methods have operator overloads:
133              
134             $u = $s + $t; # union
135             $i = $s * $t; # intersection
136             $d = $s - $t; # difference
137             $e = $s % $t; # symmetric_difference
138             $v = $s / $t; # unique
139             $c = -$s; # complement
140              
141             Both the C and C are symmetric on all
142             their arguments. For two sets they are identical but for more than
143             two sets beware: C returns true for elements
144             that are in an odd number (1, 3, 5, ...) of sets, C returns
145             true for elements that are in one set.
146              
147             Some examples of the various set differences below
148             (the _ is just used to align the elements):
149              
150             set or difference value
151              
152             $a (a b c d e _ _ _ _)
153             $b (_ _ c d e f g _ _)
154             $c (_ _ _ _ e f g h i)
155              
156             $a->difference($b) (a b _ _ _ _ _ _ _)
157             $a->symmetric_difference($b) (a b _ _ _ f g _ _)
158             $a->unique($b) (a b _ _ _ f g _ _)
159              
160             $b->difference($a) (_ _ _ _ _ f g _ _)
161             $b->symmetric_difference($a) (a b _ _ _ f g _ _)
162             $b->unique($a) (a b _ _ _ f g _ _)
163              
164             $a->difference($b, $c) (a b _ _ _ _ _ _ _)
165             $a->symmetric_difference($b, $c) (a b _ _ e _ _ h i)
166             $a->unique($b, $c) (a b _ _ _ _ _ h i)
167              
168             =head2 Comparing
169              
170             $eq = $s->is_equal($t);
171             $dj = $s->is_disjoint($t);
172             $pi = $s->is_properly_intersecting($t);
173             $ps = $s->is_proper_subset($t);
174             $pS = $s->is_proper_superset($t);
175             $is = $s->is_subset($t);
176             $iS = $s->is_superset($t);
177              
178             $cmp = $s->compare($t);
179              
180             The C method returns a string from the following list:
181             "equal", "disjoint", "proper subset", "proper superset", "proper
182             intersect", and in future (once I get around implementing it),
183             "disjoint universes".
184              
185             These methods have operator overloads:
186              
187             $eq = $s == $t; # is_equal
188             $dj = $s != $t; # is_disjoint
189             # No operator overload for is_properly_intersecting.
190             $ps = $s < $t; # is_proper_subset
191             $pS = $s > $t; # is_proper_superset
192             $is = $s <= $t; # is_subset
193             $iS = $s >= $t; # is_superset
194              
195             $cmp = $s <=> $t;
196              
197             =head2 Boolean contexts
198              
199             In Boolean contexts such as
200              
201             if ($set) { ... }
202             while ($set1 && $set2) { ... }
203              
204             the size of the C<$set> is tested, so empty sets test as false,
205             and non-empty sets as true.
206              
207             =head2 Iterating
208              
209             while (defined(my $e = $s->each)) { ... }
210              
211             This is more memory-friendly than
212              
213             for my $e ($s->elements) { ... }
214              
215             which would first construct the full list of elements and then
216             walk through it: the C<$s-Eeach> handles one element at a time.
217              
218             Analogously to using normal C in scalar context,
219             using C<$s-Eeach> has the following caveats:
220              
221             =over 4
222              
223             =item *
224              
225             The elements are returned in (apparently) random order.
226             So don't expect any particular order.
227              
228             =item *
229              
230             When no more elements remain C is returned. Since you may one
231             day have elements named C<0> don't test just like this
232              
233             while (my $e = $s->each) { ... } # WRONG!
234              
235             but instead like this
236              
237             while (defined(my $e = $s->each)) { ... } # Right.
238              
239             (An C as a set element doesn't really work, you get C<"">.)
240              
241             =item *
242              
243             There is one iterator per one set which is shared by many
244             element-accessing interfaces-- using the following will reset the
245             iterator: C, C, C, C,
246             C. C causes the iterator of the set being
247             inserted (not the set being the target of insertion) becoming reset.
248             C causes the iterators of all the participant sets becoming
249             reset. B
250             loop.> So avoid doing that.
251              
252             For C the story is a little bit more complex: it depends
253             on what element you are deleting and on the version of Perl. On modern
254             Perls you can safely delete the element you just deleted. But deleting
255             random elements can affect the iterator, so beware.
256              
257             =item *
258              
259             Modifying the set during the iteration may cause elements to be missed
260             or duplicated, or in the worst case, an endless loop; so don't do
261             that, either.
262              
263             =back
264              
265             =head2 Cartesian Product and Power Set
266              
267             =over 4
268              
269             =item *
270              
271             Cartesian product is a product of two or more sets. For two sets, it
272             is the set consisting of B of members from each set.
273             For example for the sets
274              
275             (a b)
276             (c d e)
277              
278             The Cartesian product of the above is the set
279              
280             ([a, c] [a, d] [a, e] [b, c] [b, d] [b, e])
281              
282             The [,] notation is for the ordered pairs, which sets are not.
283             This means two things: firstly, that [e, b] is B in the above
284             Cartesian product, and secondly, [b, b] is a possibility:
285              
286             (a b)
287             (b c e)
288              
289             ([a, b] [a, c] [a, e] [b, b] [b, c] [b, d])
290              
291             For example:
292              
293             my $a = Set::Scalar->new(1..2);
294             my $b = Set::Scalar->new(3..5);
295             my $c = $a->cartesian_product($b); # As an object method.
296             my $d = Set::Scalar->cartesian_product($a, $b); # As a class method.
297              
298             The $c and $d will be of the same class as $a. The members of $c and
299             $c in the above will be anonymous arrays (array references), not sets,
300             since sets wouldn't be able to represent the ordering or that a member
301             can be present more than once. Also note that since the members of
302             the input sets are unordered, the ordered pairs themselves are
303             unlikely to be in any particular order.
304              
305             If you don't want to construct the Cartesian product set, you can
306             construct an iterator and call it while it returns more members:
307              
308             my $iter = Set::Scalar->cartesian_product_iterator($a, $b, $c);
309             while (my @m = $iter->()) {
310             process(@m);
311             }
312              
313             =item *
314              
315             Power set is the set of all the subsets of a set. If the set has N
316             members, its power set has 2**N members. For example for the set
317              
318             (a b c)
319              
320             size 3, its power set is
321              
322             (() (a) (b) (c) (a b) (a c) (b c) (a b c))
323              
324             size 8. Note that since the elements of the power set are sets, they
325             are unordered, and therefore (b c) is equal to (c b). For example:
326              
327             my $a = Set::Scalar->new(1..3);
328             my $b = $a->power_set; # As an object method.
329             my $c = Set::Scalar->power_set($a); # As a class method.
330              
331             Even the empty set has a power set, of size one.
332              
333             If you don't want to construct the power set, you can construct an
334             iterator and call it until it returns no more members:
335              
336             my $iter = Set::Scalar->power_set_iterator($a);
337             my @m;
338             do {
339             @m = $iter->();
340             process(@m);
341             } while (@m);
342              
343             =back
344              
345             =head2 Customising Display
346              
347             If you want to customise the display routine you will have to
348             modify the C callback. You can modify it either
349             for all sets by using C as a class method:
350              
351             my $class_callback = sub { ... };
352              
353             Set::Scalar->as_string_callback($class_callback);
354              
355             or for specific sets by using C as an object
356             method:
357              
358             my $callback = sub { ... };
359              
360             $s1->as_string_callback($callback);
361             $s2->as_string_callback($callback);
362              
363             The anonymous subroutine gets as its first (and only) argument the
364             set to display as a string. For example to display the set C<$s>
365             as C instead of C<(a b c d e)>
366              
367             $s->as_string_callback(sub{join("-",sort $_[0]->elements)});
368              
369             If called without an argument, the current callback is returned.
370              
371             If called as a class method with undef as the only argument, the
372             original callback (the one returning C<(a b c d e)>) for all the sets
373             is restored, or if called for a single set the callback is removed
374             (and the callback for all the sets will be used).
375              
376             =head1 CAVEATS
377              
378             The first priority of Set::Scalar is to be a convenient interface to sets.
379             While not designed to be slow or big, neither has it been designed to
380             be fast or compact.
381              
382             Using references (or objects) as set members has not been extensively
383             tested. The desired semantics are not always clear: what should
384             happen when the elements behind the references change? Especially
385             unclear is what should happen when the objects start having their
386             own stringification overloads.
387              
388             =head1 SEE ALSO
389              
390             Set::Bag for bags (multisets, counted sets), and Bit::Vector for fast
391             set operations (you have to take care of the element name to bit
392             number and back mappings yourself), or Set::Infinite for sets of
393             intervals, and many more. CPAN is your friend.
394              
395             =head1 AUTHOR
396              
397             Jarkko Hietaniemi
398             David Oswald is the current maintainer.
399             The GitHub repo is at L
400              
401             =head1 COPYRIGHT AND LICENSE
402              
403             Copyright 2001,2002,2003,2004,2005,2007,2009,2013 by Jarkko Hietaniemi
404              
405             This library is free software; you can redistribute it and/or modify
406             it under the same terms as Perl itself.
407              
408             =cut
409              
410             1;