man Set::Object () - set of objects and strings

NAME

Set::Object - set of objects and strings

SYNOPSIS

  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);
      }
  }

DESCRIPTION

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 Set::Object, anything that is a reference is considered an object.

Set::Object 1.09 and later includes support for inserting scalars (including the empty string, but excluding CWundef) 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.

CLASS METHODS

new( [list] )

Return a new CWSet::Object containing the elements passed in list.

INSTANCE METHODS

insert( [list] )

Add items to the CWSet::Object.

Adding the same object several times is not an error, but any CWSet::Object will contain at most one occurence of the same object.

Returns the number of elements that were actually added.

includes( [list] )

has( [list] )

contains( [list] )

Return CWtrue if all the objects in list are members of the CWSet::Object. list may be empty, in which case CWtrue is always returned.

member( [item] )

element( [item] )

Like CWincludes, but takes a single item to check and returns that item if the value is found, rather than just a true value.

members

elements

Return the objects contained in the CWSet::Object in random (hash) order.

size

Return the number of elements in the CWSet::Object.

remove( [list] )

delete( [list] )

Remove objects from a CWSet::Object.

Removing the same object more than once, or removing an object absent from the CWSet::Object is not an error.

Returns the number of elements that were actually removed.

invert( [list] )

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 CW/, 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.

clear

Empty this CWSet::Object.

as_string

Return a textual Smalltalk-ish representation of the CWSet::Object. Also available as overloaded operator "".

intersection( [list] )

Return a new CWSet::Object containing the intersection of the CWSet::Objects passed as arguments.

Also available as overloaded operator CW*.

union( [list] )

Return a new CWSet::Object containing the union of the CWSet::Objects passed as arguments.

Also available as overloaded operator CW+.

difference ( set )

Return a new CWSet::Object containing the members of the first (invocant) set with the passed CWSet::Objects' elements removed.

Also available as overloaded operator CW-.

unique ( set )

symmetric_difference ( set )

Return a new CWSet::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 CW%.

subset( set )

Return CWtrue if this CWSet::Object is a subset of set.

Also available as operator CW<=.

proper_subset( set )

Return CWtrue if this CWSet::Object is a proper subset of set Also available as operator CW<.

superset( set )

Return CWtrue if this CWSet::Object is a superset of set. Also available as operator CW>=.

proper_superset( set )

Return CWtrue if this CWSet::Object is a proper superset of set Also available as operator CW>.

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.

compare( set )

returns one of:

  "proper intersect"
  "proper subset"
  "proper superset"
  "equal"
  "disjoint"

is_disjoint( set )

Returns a true value if the two sets have no common items.

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.

FUNCTIONS

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 Scalar::Util in preference to these functions.

blessed
Returns a true value if the passed reference (RV) is blessed. See also Acme::Holy.
reftype
A bit like the perl built-in CWref function, but returns the type of reference; ie, if the reference is blessed then it returns what CWref would have if it were not blessed. Useful for seeing through blessed references.
refaddr
Returns the memory address of a scalar. Warning: this is not guaranteed to be unique for scalars created in a program; memory might get re-used!
is_int, is_string, is_double
A quick way of checking the three bits on scalars - IOK (is_int), NOK (is_double) and POK (is_string). Note that the exact behaviour of when these bits get set is not defined by the perl API. This function returns the p versions of the macro (SvIOKp, etc); use with caution.
is_overloaded
A quick way to check if an object has overload magic on it.
ish_int
This function returns true, if the value it is passed looks like it already is a representation of an integer. This is so that you can decide whether the value passed is a hash key or an array index.
is_key
This function returns true, if the value it is passed looks more like an index to a collection than a value of a collection. 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 CWish_int) might be a good function to use to distinguish different types of indexes from values.

PERFORMANCE

The following benchmark compares CWSet::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)

AUTHOR

Original Set::Object module by Jean-Louis Leroy, <jll@skynet.be>

Set::Scalar compatibility, XS debugging and other maintainership courtesy of Sam Vilain, <samv@cpan.org>

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

Portions Copyright (c) 2003 - 2005, Sam Vilain. Same license.

SEE ALSO

perl(1), perltie(1), Set::Scalar, overload.pm