.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Set::Object 3pm" .TH Set::Object 3pm "2018-11-02" "perl v5.28.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Set::Object \- set of objects and strings .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use Set::Object qw(set); \& \& my $set = set(); # or Set::Object\->new() \& \& $set\->insert(@thingies); \& $set\->remove(@thingies); \& \& @items = @$set; # or $set\->members for the unsorted array \& \& $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); \& } \& } .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This modules implements a set of objects, that is, an unordered collection of objects without duplication. .PP The term \fIobjects\fR is applied loosely \- for the sake of Set::Object, anything that is a reference is considered an object. .PP Set::Object 1.09 and later includes support for inserting scalars (including the empty string, but excluding \f(CW\*(C`undef\*(C'\fR) 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. .SH "CONSTRUCTORS" .IX Header "CONSTRUCTORS" .SS "Set::Object\->new( [\fIlist\fP] )" .IX Subsection "Set::Object->new( [list] )" Return a new \f(CW\*(C`Set::Object\*(C'\fR containing the elements passed in \fIlist\fR. .ie n .SS """set(@members)""" .el .SS "\f(CWset(@members)\fP" .IX Subsection "set(@members)" Return a new \f(CW\*(C`Set::Object\*(C'\fR filled with \f(CW@members\fR. You have to explicitly import this method. .PP \&\fBNew in Set::Object 1.22\fR: this function is now called as a method to return new sets the various methods that return a new set, such as \&\f(CW\*(C`\->intersection\*(C'\fR, \f(CW\*(C`\->union\*(C'\fR, etc and their overloaded counterparts. The default method always returns \f(CW\*(C`Set::Object\*(C'\fR objects, preserving previous behaviour and not second guessing the nature of your derived Set::Object class. .ie n .SS """weak_set()""" .el .SS "\f(CWweak_set()\fP" .IX Subsection "weak_set()" Return a new \f(CW\*(C`Set::Object::Weak\*(C'\fR, filled with \f(CW@members\fR. You have to explicitly import this method. .SH "INSTANCE METHODS" .IX Header "INSTANCE METHODS" .SS "insert( [\fIlist\fP] )" .IX Subsection "insert( [list] )" Add items to the \f(CW\*(C`Set::Object\*(C'\fR. .PP Adding the same object several times is not an error, but any \&\f(CW\*(C`Set::Object\*(C'\fR will contain at most one occurrence of the same object. .PP Returns the number of elements that were actually added. As of Set::Object 1.23, \f(CW\*(C`undef\*(C'\fR will not insert. .SS "includes( [\fIlist\fP] )" .IX Subsection "includes( [list] )" .SS "has( [\fIlist\fP] )" .IX Subsection "has( [list] )" .SS "contains( [\fIlist\fP] )" .IX Subsection "contains( [list] )" Return \f(CW\*(C`true\*(C'\fR if \fBall\fR the objects in \fIlist\fR are members of the \&\f(CW\*(C`Set::Object\*(C'\fR. \fIlist\fR may be empty, in which case \f(CW\*(C`true\*(C'\fR is always returned. .PP As of Set::Object 1.23, \f(CW\*(C`undef\*(C'\fR will never appear to be present in any set (even if the set contains the empty string). Prior to 1.23, there would have been a run-time warning. .SS "member( [\fIitem\fP] )" .IX Subsection "member( [item] )" .SS "element( [\fIitem\fP] )" .IX Subsection "element( [item] )" Like \f(CW\*(C`includes\*(C'\fR, but takes a single item to check and returns that item if the value is found, rather than just a true value. .SS "members" .IX Subsection "members" .SS "elements" .IX Subsection "elements" Return the objects contained in the \f(CW\*(C`Set::Object\*(C'\fR in random (hash) order. .PP Note that the elements of a \f(CW\*(C`Set::Object\*(C'\fR in list context are returned sorted \- \f(CW@$set\fR \- so using the \f(CW\*(C`members\*(C'\fR method is much faster. .SS "size" .IX Subsection "size" Return the number of elements in the \f(CW\*(C`Set::Object\*(C'\fR. .SS "remove( [\fIlist\fP] )" .IX Subsection "remove( [list] )" .SS "delete( [\fIlist\fP] )" .IX Subsection "delete( [list] )" Remove objects from a \f(CW\*(C`Set::Object\*(C'\fR. .PP Removing the same object more than once, or removing an object absent from the \f(CW\*(C`Set::Object\*(C'\fR is not an error. .PP Returns the number of elements that were actually removed. .PP As of Set::Object 1.23, removing \f(CW\*(C`undef\*(C'\fR is safe (but having an \&\f(CW\*(C`undef\*(C'\fR in the passed in list does not increase the return value, because it could never be in the set) .SS "weaken" .IX Subsection "weaken" Makes all the references in the set \*(L"weak\*(R" \- that is, they do not increase the reference count of the object they point to, just like Scalar::Util's \f(CW\*(C`weaken\*(C'\fR function. .PP This was introduced with Set::Object 1.16, and uses a brand new type of magic. \fBUse with caution\fR. If you get segfaults when you use \&\f(CW\*(C`weaken\*(C'\fR, please reduce your problem to a test script before submission. .PP \&\fBNew:\fR as of Set::Object 1.19, you may use the \f(CW\*(C`weak_set\*(C'\fR function to make weak sets, or \f(CW\*(C`Set::Object::Weak\->new\*(C'\fR, or import the \&\f(CW\*(C`set\*(C'\fR constructor from \f(CW\*(C`Set::Object::Weak\*(C'\fR instead. See Set::Object::Weak for more. .PP \&\fBNote to people sub-classing \f(CB\*(C`Set::Object\*(C'\fB:\fR this method re-blesses the invocant to \f(CW\*(C`Set::Object::Weak\*(C'\fR. Override the method \f(CW\*(C`weak_pkg\*(C'\fR in your sub-class to control this behaviour. .SS "is_weak" .IX Subsection "is_weak" Returns a true value if this set is a weak set. .SS "strengthen" .IX Subsection "strengthen" Turns a weak set back into a normal one. .PP \&\fBNote to people sub-classing \f(CB\*(C`Set::Object\*(C'\fB:\fR this method re-blesses the invocant to \f(CW\*(C`Set::Object\*(C'\fR. Override the method \f(CW\*(C`strong_pkg\*(C'\fR in your sub-class to control this behaviour. .SS "invert( [\fIlist\fP] )" .IX Subsection "invert( [list] )" For each item in \fIlist\fR, it either removes it or adds it to the set, so that a change is always made. .PP Also available as the overloaded operator \f(CW\*(C`/\*(C'\fR, 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. .SS "clear" .IX Subsection "clear" Empty this \f(CW\*(C`Set::Object\*(C'\fR. .SS "as_string" .IX Subsection "as_string" Return a textual Smalltalk-ish representation of the \f(CW\*(C`Set::Object\*(C'\fR. Also available as overloaded operator "". .SS "equal( \fIset\fP )" .IX Subsection "equal( set )" Returns a true value if \fIset\fR contains exactly the same members as the invocant. .PP Also available as overloaded operator \f(CW\*(C`==\*(C'\fR (or \f(CW\*(C`eq\*(C'\fR). .SS "not_equal( \fIset\fP )" .IX Subsection "not_equal( set )" Returns a false value if \fIset\fR contains exactly the same members as the invocant. .PP Also available as overloaded operator \f(CW\*(C`!=\*(C'\fR (or \f(CW\*(C`ne\*(C'\fR). .SS "intersection( [\fIlist\fP] )" .IX Subsection "intersection( [list] )" Return a new \f(CW\*(C`Set::Object\*(C'\fR containing the intersection of the \&\f(CW\*(C`Set::Object\*(C'\fRs passed as arguments. .PP Also available as overloaded operator \f(CW\*(C`*\*(C'\fR. .SS "union( [\fIlist\fP] )" .IX Subsection "union( [list] )" Return a new \f(CW\*(C`Set::Object\*(C'\fR containing the union of the \&\f(CW\*(C`Set::Object\*(C'\fRs passed as arguments. .PP Also available as overloaded operator \f(CW\*(C`+\*(C'\fR. .SS "difference ( \fIset\fP )" .IX Subsection "difference ( set )" Return a new \f(CW\*(C`Set::Object\*(C'\fR containing the members of the first (invocant) set with the passed \f(CW\*(C`Set::Object\*(C'\fRs' elements removed. .PP Also available as overloaded operator \f(CW\*(C`\-\*(C'\fR. .SS "unique ( \fIset\fP )" .IX Subsection "unique ( set )" .SS "symmetric_difference ( \fIset\fP )" .IX Subsection "symmetric_difference ( set )" Return a new \f(CW\*(C`Set::Object\*(C'\fR containing the members of all passed sets (including the invocant), with common elements removed. This will be the opposite (complement) of the \fIintersection\fR of the two sets. .PP Also available as overloaded operator \f(CW\*(C`%\*(C'\fR. .SS "subset( \fIset\fP )" .IX Subsection "subset( set )" Return \f(CW\*(C`true\*(C'\fR if this \f(CW\*(C`Set::Object\*(C'\fR is a subset of \fIset\fR. .PP Also available as operator \f(CW\*(C`<=\*(C'\fR. .SS "proper_subset( \fIset\fP )" .IX Subsection "proper_subset( set )" Return \f(CW\*(C`true\*(C'\fR if this \f(CW\*(C`Set::Object\*(C'\fR is a proper subset of \fIset\fR Also available as operator \f(CW\*(C`<\*(C'\fR. .SS "superset( \fIset\fP )" .IX Subsection "superset( set )" Return \f(CW\*(C`true\*(C'\fR if this \f(CW\*(C`Set::Object\*(C'\fR is a superset of \fIset\fR. Also available as operator \f(CW\*(C`>=\*(C'\fR. .SS "proper_superset( \fIset\fP )" .IX Subsection "proper_superset( set )" Return \f(CW\*(C`true\*(C'\fR if this \f(CW\*(C`Set::Object\*(C'\fR is a proper superset of \fIset\fR Also available as operator \f(CW\*(C`>\*(C'\fR. .SS "is_null( \fIset\fP )" .IX Subsection "is_null( set )" Returns a true value if this set does not contain any members, that is, if its size is zero. .SH "Set::Scalar compatibility methods" .IX Header "Set::Scalar compatibility methods" By and large, Set::Object is not and probably never will be feature-compatible with Set::Scalar; however the following functions are provided anyway. .SS "compare( \fIset\fP )" .IX Subsection "compare( set )" returns one of: .PP .Vb 5 \& "proper intersect" \& "proper subset" \& "proper superset" \& "equal" \& "disjoint" .Ve .SS "is_disjoint( \fIset\fP )" .IX Subsection "is_disjoint( set )" Returns a true value if the two sets have no common items. .SS "as_string_callback( \fIset\fP )" .IX Subsection "as_string_callback( set )" 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. .SH "FUNCTIONS" .IX Header "FUNCTIONS" The following functions are defined by the Set::Object \s-1XS\s0 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. .PP Please use the versions in Scalar::Util in preference to these functions. In fact, if you use these functions in your production code then you may have to rewrite it some day. They are retained only because they are \*(L"mostly harmless\*(R". .IP "\fBblessed\fR" 4 .IX Item "blessed" \&\fBDo not use in production code\fR .Sp Returns a true value if the passed reference (\s-1RV\s0) is blessed. See also Acme::Holy. .IP "\fBreftype\fR" 4 .IX Item "reftype" \&\fBDo not use in production code\fR .Sp A bit like the perl built-in \f(CW\*(C`ref\*(C'\fR function, but returns the \fItype\fR of reference; ie, if the reference is blessed then it returns what \&\f(CW\*(C`ref\*(C'\fR would have if it were not blessed. Useful for \*(L"seeing through\*(R" blessed references. .IP "\fBrefaddr\fR" 4 .IX Item "refaddr" \&\fBDo not use in production code\fR .Sp Returns the memory address of a scalar. \fBWarning\fR: this is \fInot\fR guaranteed to be unique for scalars created in a program; memory might get re-used! .IP "\fBis_int\fR, \fBis_string\fR, \fBis_double\fR" 4 .IX Item "is_int, is_string, is_double" \&\fBDo not use in production code\fR .Sp A quick way of checking the three bits on scalars \- \s-1IOK\s0 (is_int), \s-1NOK\s0 (is_double) and \s-1POK\s0 (is_string). Note that the exact behaviour of when these bits get set is not defined by the perl \s-1API.\s0 .Sp This function returns the \*(L"p\*(R" versions of the macro (SvIOKp, etc); use with caution. .IP "\fBis_overloaded\fR" 4 .IX Item "is_overloaded" \&\fBDo not use in production code\fR .Sp A quick way to check if an object has overload magic on it. .IP "\fBish_int\fR" 4 .IX Item "ish_int" \&\fBDeprecated and will be removed in 2014\fR .Sp This function returns true, if the value it is passed looks like it \&\fIalready is\fR a representation of an \fIinteger\fR. This is so that you can decide whether the value passed is a hash key or an array index. .IP "\fBis_key\fR" 4 .IX Item "is_key" \&\fBDeprecated and will be removed in 2014\fR .Sp This function returns true, if the value it is passed looks more like an \fIindex\fR to a collection than a \fIvalue\fR of a collection. Similar to the looks_like_number internal function, but weird. Avoid. .IP "\fBget_magic\fR" 4 .IX Item "get_magic" \&\fBDo not use in production code\fR .Sp Pass to a scalar, and get the magick wand (\f(CW\*(C`mg_obj\*(C'\fR) used by the weak set implementation. The return will be a list of integers which are pointers to the actual \f(CW\*(C`ISET\*(C'\fR 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. .SH "CLASS METHODS" .IX Header "CLASS METHODS" These class methods are probably only interesting to those sub-classing \f(CW\*(C`Set::Object\*(C'\fR. .IP "strong_pkg" 4 .IX Item "strong_pkg" When a set that was already weak is strengthened using \&\f(CW\*(C`\->strengthen\*(C'\fR, it gets re-blessed into this package. .IP "weak_pkg" 4 .IX Item "weak_pkg" When a set that was \s-1NOT\s0 already weak is weakened using \&\f(CW\*(C`\->weaken\*(C'\fR, it gets re-blessed into this package. .IP "tie_array_pkg" 4 .IX Item "tie_array_pkg" When the object is accessed as an array, tie the array into this package. .IP "tie_hash_pkg" 4 .IX Item "tie_hash_pkg" When the object is accessed as a hash, tie the hash into this package. .SH "SERIALIZATION" .IX Header "SERIALIZATION" It is possible to serialize \f(CW\*(C`Set::Object\*(C'\fR objects via Storable and duplicate via \f(CW\*(C`dclone\*(C'\fR; such support was added in release 1.04. As of \f(CW\*(C`Set::Object\*(C'\fR version 1.15, it is possible to freeze scalar items, too. .PP However, the support for freezing scalar items introduced a backwards incompatibility. Earlier versions than 1.15 will \f(CW\*(C`thaw\*(C'\fR sets frozen using Set::Object 1.15 and later as a set with one item \- an array that contains the actual members. .PP Additionally, version 1.15 had a bug that meant that it would not detect \f(CW\*(C`freeze\*(C'\fR protocol upgrades, instead reverting to pre\-1.15 behaviour. .PP \&\f(CW\*(C`Set::Object\*(C'\fR 1.16 and above are capable of dealing correctly with all serialized forms, as well as correctly aborting if a \*(L"newer\*(R" \&\f(CW\*(C`freeze\*(C'\fR protocol is detected during \f(CW\*(C`thaw\*(C'\fR. .SH "PERFORMANCE" .IX Header "PERFORMANCE" The following benchmark compares \f(CW\*(C`Set::Object\*(C'\fR with using a hash to emulate a set-like collection (this is an old benchmark, but still holds true): .PP .Vb 1 \& use Set::Object; \& \& package Obj; \& sub new { bless { } } \& \& @els = map { Obj\->new() } 1..1000; \& \& require Benchmark; \& \& Benchmark::timethese(100, { \& \*(AqControl\*(Aq => sub { }, \& \*(AqH insert\*(Aq => sub { my %h = (); @h{@els} = @els; }, \& \*(AqS insert\*(Aq => 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, { \& \*(AqH lookup\*(Aq => sub { exists $gh{33} }, \& \*(AqS lookup\*(Aq => sub { $gs\->includes($el) } \& } ); .Ve .PP On my computer the results are: .PP .Vb 8 \& 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) .Ve .SH "THREAD SAFETY" .IX Header "THREAD SAFETY" This module is not thread-safe. .SH "AUTHOR" .IX Header "AUTHOR" Original Set::Object module by Jean-Louis Leroy, .PP Set::Scalar compatibility, \s-1XS\s0 debugging, weak references support courtesy of Sam Vilain, . .PP New maintainer is Reini Urban . Patches against please. Tickets at \s-1RT\s0 .SH "LICENCE" .IX Header "LICENCE" 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, either the original, or at your option, any later version. .PP Portions Copyright (c) 2003 \- 2005, Sam Vilain. Same license. .PP Portions Copyright (c) 2006, 2007, Catalyst \s-1IT\s0 (\s-1NZ\s0) Limited. This module is free software. It may be used, redistributed and/or modified under the terms of the Perl Artistic License .PP Portions Copyright (c) 2013, cPanel. Same license. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fBperl\fR\|(1), \fBperltie\fR\|(1), Set::Scalar, overload