Set::Object - set of objects and strings |
Set::Object - set of objects and strings
use Set::Object;
my $set = set(); # or Set::Object->new()
$set->insert(@thingies); $set->remove(@thingies);
@items = @$set; # or $set->members;
$union = $set1 + $set2; $intersection = $set1 * $set2; $difference = $set1 - $set2; $symmetric_difference = $set1 % $set2;
print "set1 is a proper subset of set2" if $set1 < $set2;
print "set1 is a subset of set2" if $set1 <= $set2;
# common idiom - iterate over any pure Perl structure use Set::Object qw(reftype); my @stack = $root; my $seen = Set::Object->new(@stack); while (my $object = pop @stack) { if (reftype $object eq "HASH") { # do something with hash members
# add the new nodes to the stack push @stack, grep { ref $_ && $seen->insert($_) } values %$object; } elsif (reftype $object eq "ARRAY") { # do something with array members
# add the new nodes to the stack push @stack, grep { ref $_ && $seen->insert($_) } @$object;
} elsif (reftype $object =~ /SCALAR|REF/) { push @stack, $$object if ref $$object && $seen->insert($$object); } }
This modules implements a set of objects, that is, an unordered collection of objects without duplication.
The term objects is applied loosely - for the sake of the Set::Object manpage, anything that is a reference is considered an object.
the Set::Object manpage 1.09 and later includes support for inserting scalars
(including the empty string, but excluding undef
) as well as
objects. This can be thought of as (and is currently implemented as)
a degenerate hash that only has keys and no values. Unlike objects
placed into a Set::Object, scalars that are inserted will be flattened
into strings, so will lose any magic (eg, tie) or other special bits
that they went in with; only strings come out.
Return a new Set::Object
containing the elements passed in list.
set(@members)
Return a new Set::Object
filled with @members
. You have to
explicitly import this method.
New in Set::Object 1.22: this function is now called as a method
to return new sets the various methods that return a new set, such as
->intersection
, ->union
, etc and their overloaded
counterparts. The default method always returns Set::Object
objects, preserving previous behaviour and not second guessing the
nature of your derived the Set::Object manpage class.
weak_set()
Return a new Set::Object::Weak
, filled with @members
. You have
to explicitly import this method.
Add items to the Set::Object
.
Adding the same object several times is not an error, but any
Set::Object
will contain at most one occurence of the same object.
Returns the number of elements that were actually added.
Return true
if all the objects in list are members of the
Set::Object
. list may be empty, in which case true
is
always returned.
Like includes
, but takes a single item to check and returns that
item if the value is found, rather than just a true value.
Return the objects contained in the Set::Object
in random (hash)
order.
Return the number of elements in the Set::Object
.
Remove objects from a Set::Object
.
Removing the same object more than once, or removing an object absent
from the Set::Object
is not an error.
Returns the number of elements that were actually removed.
Makes all the references in the set ``weak'' - that is, they do not
increase the reference count of the object they point to, just like
Scalar::Util's weaken
function.
This was introduced with Set::Object 1.16, and uses a brand new type
of magic. Use with caution. If you get segfaults when you use
weaken
, please reduce your problem to a test script before
submission.
New: as of Set::Object 1.19, you may use the weak_set
function
to make weak sets, or Set::Object::Weak->new
, or import the
set
constructor from Set::Object::Weak
instead. See
the Set::Object::Weak manpage for more.
Note to people sub-classing Set::Object
: this method re-blesses
the invocant to Set::Object::Weak
. Override the method weak_pkg
in your sub-class to control this behaviour.
Returns a true value if this set is a weak set.
Turns a weak set back into a normal one.
Note to people sub-classing Set::Object
: this method re-blesses
the invocant to Set::Object
. Override the method strong_pkg
in
your sub-class to control this behaviour.
For each item in list, it either removes it or adds it to the set, so that a change is always made.
Also available as the overloaded operator /
, in which case it
expects another set (or a single scalar element), and returns a new
set that is the original set with all the second set's items inverted.
Empty this Set::Object
.
Return a textual Smalltalk-ish representation of the Set::Object
.
Also available as overloaded operator ``''.
Returns a true value if set contains exactly the same members as the invocant.
Also available as overloaded operator ==
(or eq
).
Returns a false value if set contains exactly the same members as the invocant.
Also available as overloaded operator !=
(or ne
).
Return a new Set::Object
containing the intersection of the
Set::Object
s passed as arguments.
Also available as overloaded operator *
.
Return a new Set::Object
containing the union of the
Set::Object
s passed as arguments.
Also available as overloaded operator +
.
Return a new Set::Object
containing the members of the first
(invocant) set with the passed Set::Object
s' elements removed.
Also available as overloaded operator -
.
Return a new Set::Object
containing the members of all passed sets
(including the invocant), with common elements removed. This will be
the opposite (complement) of the intersection of the two sets.
Also available as overloaded operator %
.
Return true
if this Set::Object
is a subset of set.
Also available as operator <=
.
Return true
if this Set::Object
is a proper subset of set
Also available as operator <
.
Return true
if this Set::Object
is a superset of set.
Also available as operator >=
.
Return true
if this Set::Object
is a proper superset of set
Also available as operator >
.
Returns a true value if this set does not contain any members, that is, if its size is zero.
By and large, the Set::Object manpage is not and probably never will be feature-compatible with the Set::Scalar manpage; however the following functions are provided anyway.
returns one of:
"proper intersect" "proper subset" "proper superset" "equal" "disjoint"
Returns a true value if the two sets have no common items.
Allows you to define a custom stringify function. This is only a class method. If you want anything fancier than this, you should sub-class Set::Object.
The following functions are defined by the Set::Object XS code for convenience; they are largely identical to the versions in the Scalar::Util module, but there are a couple that provide functions not catered to by that module.
Please use the versions in the Scalar::Util manpage in preference to these functions.
ref
function, but returns the type
of reference; ie, if the reference is blessed then it returns what
ref
would have if it were not blessed. Useful for ``seeing through''
blessed references.
This function returns the ``p'' versions of the macro (SvIOKp, etc); use with caution.
But wait, you say - Set::Object has no indices, one of the fundamental
properties of a Set is that it is an unordered collection. Which
means no indices. Well, if this module were ever to be derived to
be a more general multi-purpose collection, then this (and ish_int
)
might be a good function to use to distinguish different types of
indexes from values.
mg_obj
) used by the weak
set implementation. The return will be a list of integers which are
pointers to the actual ISET
structure. Whatever you do don't
change the array :). This is used only by the test suite, and if you
find it useful for something then you should probably conjure up a
test suite and send it to me, otherwise it could get pulled.
These class methods are probably only interesting to those
sub-classing Set::Object
.
->strengthen
, it gets re-blessed into this package.
->weaken
, it gets re-blessed into this package.
It is possible to serialize Set::Object
objects via the Storable manpage and
duplicate via dclone
; such support was added in release 1.04. As
of Set::Object
version 1.15, it is possible to freeze scalar items,
too.
However, the support for freezing scalar items introduced a backwards
incompatibility. Earlier versions than 1.15 will thaw
sets frozen
using Set::Object 1.15 and later as a set with one item - an array
that contains the actual members.
Additionally, version 1.15 had a bug that meant that it would not
detect freeze
protocol upgrades, instead reverting to pre-1.15
behaviour.
Set::Object
1.16 and above are capable of dealing correctly with
all serialized forms, as well as correctly aborting if a ``newer''
freeze
protocol is detected during thaw
.
The following benchmark compares Set::Object
with using a hash to
emulate a set-like collection (this is an old benchmark, but still
holds true):
use Set::Object;
package Obj; sub new { bless { } }
@els = map { Obj->new() } 1..1000;
require Benchmark;
Benchmark::timethese(100, { 'Control' => sub { }, 'H insert' => sub { my %h = (); @h{@els} = @els; }, 'S insert' => sub { my $s = Set::Object->new(); $s->insert(@els) }, } );
%gh = (); @gh{@els} = @els;
$gs = Set::Object->new(@els); $el = $els[33];
Benchmark::timethese(100_000, { 'H lookup' => sub { exists $gh{33} }, 'S lookup' => sub { $gs->includes($el) } } );
On my computer the results are:
Benchmark: timing 100 iterations of Control, H insert, S insert... Control: 0 secs ( 0.01 usr 0.00 sys = 0.01 cpu) (warning: too few iterations for a reliable count) H insert: 68 secs (67.81 usr 0.00 sys = 67.81 cpu) S insert: 9 secs ( 8.81 usr 0.00 sys = 8.81 cpu) Benchmark: timing 100000 iterations of H lookup, S lookup... H lookup: 7 secs ( 7.14 usr 0.00 sys = 7.14 cpu) S lookup: 6 secs ( 5.94 usr 0.00 sys = 5.94 cpu)
Original Set::Object module by Jean-Louis Leroy, <jll@skynet.be>
Set::Scalar compatibility, XS debugging, weak references support and general maintainership courtesy of Sam Vilain, <samv@cpan.org>. Maximum respect to those who send me test scripts, enhancements, etc as patches against my git tree, browsable at http://utsl.gen.nz/gitweb/.
Copyright (c) 1998-1999, Jean-Louis Leroy. All Rights Reserved. This module is free software. It may be used, redistributed and/or modified under the terms of the Perl Artistic License
Portions Copyright (c) 2003 - 2005, Sam Vilain. Same license.
Portions Copyright (c) 2006, 2007, Catalyst IT (NZ) Limited. Same license.
perl(1), perltie(1), the Set::Scalar manpage, overload.pm
Set::Object - set of objects and strings |