SPUG: a technique for avoiding circularity

Fred Morris m3047 at inwa.net
Wed Sep 17 14:27:27 CDT 2003


The issue came up at last evening's meeting of avoiding circularity. In
addition to circular lists, this can come up in object-oriented collections
where all members of the collection need to be "aware" of other members of
the collection: typically this is done by their being aware of some sort of
"connector".

I hearken back to the patent on canonical storage of numbers on
network-accessible storage, which claimed that K&R said that this was a
"problem".. in spite of the fact that K&R carefully elucidated the
canonicalization which the compiler itself used to manipulate numbers of
dissimilar machine types... I actually wrote to somebody about it, and as I
recall they wrote back and said would I please not tell anybody... oh well.
So I want to be careful saying circularity is a problem in need of a
solution, because it's not; nonetheless in these days of diminishing herds,
people are keen to put a brand on anything that moves.


With that apologaeia here is an old, tried and true technique which is
particularly convenient given Perl's free and easy attitude towards name
spaces (although it can be accomplished in almost any language with a
little bit of craft). With a nod to Asa Mercer, I hope you enjoy it.

--

Fred Morris
m3047 at inwa.net

--

#!/usr/bin/perl -w

use strict;

# -=-=- MARKET, connecting scoundrels everywhere -=-=-

package Market;

my %Markets;

sub new {

    my $class = shift;
    my $name = shift;

    my $self = { name_ => $name };
    bless $self, $class;
    $Markets{ $name } = $self;

    return $self;

} # &new

sub add {

    my $self = shift;

    foreach my $item (@_) {
        $self->{$item->{name_}} = $item;
        $item->{market} = $self->{name_}
    }

    return $self;

} # &add

sub locate {

    my $market_name = shift;
    my $actor_name = shift;

    return $Markets{$market_name}{$actor_name};

} # &locate

sub crash {

    my $self = shift;

    return delete $Markets{$self->{name_}};

} # &crash

sub markets() {

    return join ' ', keys %Markets;

} # &markets

# -=-=- COWBOY, base class for scoundrels -=-=-

package Cowboy;

sub ilk {

    my $self = shift;
    my $name = shift;

    return Market::locate( $self->{market}, $name );

} # &ilk

# -=-=- OLDSCHOOL, ah the wild west... -=-=-

package OldSchool;

use vars qw/ @ISA /;

@ISA = qw( Cowboy );

sub new {

    my $class = shift;
    my $name = shift;

    my $self = { name_ => $name };
    bless $self, $class;

    return $self;

} # &new

sub excuse {

    my $self = shift;

    return "$self->{name_} says: they stole my cows\n";

} # &excuse

# -=-=- KINDERRICHER, of course things are different now. -=-=-

package KinderRicher;

use vars qw/ @ISA /;

@ISA = qw( Cowboy );

sub new {

    my $class = shift;
    my $name = shift;

    my $self = { name_ => $name };
    bless $self, $class;

    return $self;

} # &new

sub excuse {

    my $self = shift;

    return "$self->{name_} says: they stole my intellectual property\n";

} # &excuse

# -=-=- MAIN, the actors on the stage -=-=-

package main;

my $market = Market->new( 'Financial' );

my @banditti;

push @banditti, OldSchool->new('Greely');
push @banditti, KinderRicher->new('Billy');

$market->add( @banditti );

print $banditti[0]->excuse();

print $banditti[0]->ilk($banditti[1]{name_})->excuse();

print "before: ", Market::markets(), "\n";

$market->crash();

print "after: ", Market::markets(), "\n";





More information about the spug-list mailing list