File Coverage

blib/lib/Anansi/ObjectManager.pm
Criterion Covered Total %
statement 31 243 12.7
branch 11 250 4.4
condition n/a
subroutine 6 14 42.8
pod 13 13 100.0
total 61 520 11.7


line stmt bran cond sub pod time code
1             package Anansi::ObjectManager;
2              
3              
4             =head1 NAME
5              
6             Anansi::ObjectManager - A module object encapsulation manager
7              
8             =head1 SYNOPSIS
9              
10             package Anansi::Example;
11              
12             use Anansi::ObjectManager;
13              
14             sub DESTROY {
15             my ($self) = @_;
16             my $objectManager = Anansi::ObjectManager->new();
17             if(1 == $objectManager->registrations($self)) {
18             $objectManager->obsolete(
19             USER => $self,
20             );
21             $objectManager->unregister($self);
22             }
23             }
24              
25             sub new {
26             my ($class, %parameters) = @_;
27             return if(ref($class) =~ /^ (ARRAY|CODE|FORMAT|GLOB|HASH|IO|LVALUE|REF|Regexp|SCALAR|VSTRING)$/i);
28             $class = ref($class) if(ref($class) !~ /^$/);
29             my $self = {
30             NAMESPACE => $class,
31             PACKAGE => __PACKAGE__,
32             };
33             bless($self, $class);
34             my $objectManager = Anansi::ObjectManager->new();
35             $objectManager->register($self);
36             return $self;
37             }
38              
39             1;
40              
41             package main;
42              
43             use Anansi::Example;
44              
45             my $object = Anansi::Example->new();
46              
47             1;
48              
49             =head1 DESCRIPTION
50              
51             This is a manager for encapsulating module objects within other module objects
52             and ensures that the memory used by any module object will only be garbage
53             collected by the perl run time environment when the module object is no longer
54             used. Many of the subroutines/methods declared by this module are for internal
55             use only but are provided in this context for purposes of module extension.
56              
57             =cut
58              
59              
60             our $VERSION = '0.08';
61              
62             my $NAMESPACE;
63              
64             my $OBJECTMANAGER = Anansi::ObjectManager->new();
65              
66              
67             =head1 METHODS
68              
69             =cut
70              
71              
72             =head2 current
73              
74             my $someObject = Some::Example->new();
75             $someObject->{ANOTHER_OBJECT} = Another::Example->new();
76             my $objectManager = Anansi::ObjectManager->new();
77             $objectManager->current(
78             USER => $someObject,
79             USES => $someObject->{ANOTHER_OBJECT},
80             );
81              
82             my $someObject = Some::Example->new();
83             $someObject->{ANOTHER_OBJECT} = Another::Example->new();
84             $someObject->{YET_ANOTHER_OBJECT} = Yet::Another::Example->new();
85             my $objectManager = Anansi::ObjectManager->new();
86             $objectManager->current(
87             USER => $someObject,
88             USES => [$someObject->{ANOTHER_OBJECT}, $someObject->{YET_ANOTHER_OBJECT}],
89             );
90              
91             =over 4
92              
93             =item self I<(Blessed Hash, Required)>
94              
95             An object of this namespace.
96              
97             =item parameters I<(Hash, Required)>
98              
99             Named parameters.
100              
101             =over 4
102              
103             =item USER I<(Blessed Hash, Required)>
104              
105             The object that needs the I objects to only be garbage collected at some
106             time after it has finished using them. This object may be garbage collected at
107             any time after the Perl interpreter has determined that it is no longer in use.
108              
109             =item USES I<(Blessed Hash B Array, Required)>
110              
111             Either an object or an array of objects that the I object needs to only be
112             garbage collected at some time after it has finished using them.
113              
114             =back
115              
116             =back
117              
118             Ensures that a module object instance is tied to one or more module object
119             instances to ensure that those object instances are terminated after the tying
120             object instance. This allows a tying object to make full use of the tied
121             objects up to the moment of termination.
122              
123             =cut
124              
125              
126             sub current {
127 0     0 1 0 my ($self, %parameters) = @_;
128 0 0       0 return if(!defined($parameters{USER}));
129 0 0       0 return if(ref($parameters{USER}) =~ /^(|ARRAY|CODE|FORMAT|GLOB|HASH|IO|LVALUE|REF|Regexp|SCALAR|VSTRING)$/i);
130 0         0 my $user = $parameters{USER};
131 0 0       0 return if(!defined($parameters{USES}));
132 0 0       0 if(ref($parameters{USES}) =~ /^(|CODE|FORMAT|GLOB|HASH|IO|LVALUE|REF|Regexp|SCALAR|VSTRING)$/i) {
    0          
133 0         0 return;
134             } elsif(ref($parameters{USES}) =~ /^ARRAY$/i) {
135 0 0       0 $self->register($user) if(!defined($user->{IDENTIFICATION}));
136 0         0 my $userIndex = $self->identification($user->{IDENTIFICATION});
137 0 0       0 if(!defined($userIndex)) {
138 0         0 $self->register($user);
139 0         0 $userIndex = $self->identification($user->{IDENTIFICATION});
140             }
141 0         0 my @users = ($userIndex);
142 0         0 for(my $index = 0; $index < scalar(@users); $index++) {
143 0         0 for(my $instance = 0; $instance < scalar(@{$self->{IDENTIFICATIONS}}); $instance++) {
  0         0  
144 0 0       0 next if($index == $instance);
145 0 0       0 next if(!defined($self->{'INSTANCE_'.$users[$index]}->{'USER_'.$instance}));
146 0 0       0 next if(!defined($self->{'INSTANCE_'.$instance}));
147 0         0 my $found;
148 0         0 for($found = 0; $found < scalar(@users); $found++) {
149 0 0       0 last if($instance == $found);
150             }
151 0 0       0 push(@users, $instance) if($found == scalar(@users));
152             }
153             }
154 0         0 foreach my $uses (@{$parameters{USES}}) {
  0         0  
155 0 0       0 next if(ref($uses) =~ /^(|CODE|FORMAT|GLOB|HASH|IO|LVALUE|REF|Regexp|SCALAR|VSTRING)$/i);
156 0 0       0 $self->register($uses) if(!defined($uses->{IDENTIFICATION}));
157 0         0 my $usesIndex = $self->identification($uses->{IDENTIFICATION});
158 0 0       0 if(!defined($usesIndex)) {
159 0         0 $self->register($uses);
160 0         0 $usesIndex = $self->identification($uses->{IDENTIFICATION});
161             }
162 0 0       0 if(!defined($uses->{'USER_'.$userIndex})) {
163 0         0 my $found;
164 0         0 for($found = 0; $found < scalar(@users); $found++) {
165 0 0       0 last if($usesIndex == $found);
166             }
167 0 0       0 $uses->{'USER_'.$userIndex} = $user if($found == scalar(@users));
168             }
169             }
170             } else {
171 0 0       0 $self->register($user) if(!defined($user->{IDENTIFICATION}));
172 0         0 my $userIndex = $self->identification($user->{IDENTIFICATION});
173 0 0       0 if(!defined($userIndex)) {
174 0         0 $self->register($user);
175 0         0 $userIndex = $self->identification($user->{IDENTIFICATION});
176             }
177 0         0 my @users = ($userIndex);
178 0         0 for(my $index = 0; $index < scalar(@users); $index++) {
179 0         0 for(my $instance = 0; $instance < scalar(@{$self->{IDENTIFICATIONS}}); $instance++) {
  0         0  
180 0 0       0 next if($index == $instance);
181 0 0       0 next if(!defined($self->{'INSTANCE_'.$users[$index]}->{'USER_'.$instance}));
182 0 0       0 next if(!defined($self->{'INSTANCE_'.$instance}));
183 0         0 my $found;
184 0         0 for($found = 0; $found < scalar(@users); $found++) {
185 0 0       0 last if($instance == $found);
186             }
187 0 0       0 push(@users, $instance) if($found == scalar(@users));
188             }
189             }
190 0         0 my $uses = $parameters{USES};
191 0 0       0 $self->register($uses) if(!defined($uses->{IDENTIFICATION}));
192 0         0 my $usesIndex = $self->identification($uses->{IDENTIFICATION});
193 0 0       0 if(!defined($usesIndex)) {
194 0         0 $self->register($uses);
195 0         0 $usesIndex = $self->identification($uses->{IDENTIFICATION});
196             }
197 0 0       0 if(!defined($uses->{'USER_'.$userIndex})) {
198 0         0 my $found;
199 0         0 for($found = 0; $found < scalar(@users); $found++) {
200 0 0       0 last if($usesIndex == $found);
201             }
202 0 0       0 $uses->{'USER_'.$userIndex} = $user if($found == scalar(@users));
203             }
204             }
205             }
206              
207              
208             =head2 finalise
209              
210             package Some::Example;
211              
212             use base qw(Anansi::ObjectManager);
213              
214             sub old {
215             my ($self, %parameters) = @_;
216             $self->finalise();
217             }
218              
219             1;
220              
221             =over 4
222              
223             =item self I<(Blessed Hash, Required)>
224              
225             An object of this namespace.
226              
227             =item parameters I<(Hash, Optional)>
228              
229             Named parameters.
230              
231             =back
232              
233             Ensures that all of the known object instances are allowed to terminate in
234             reverse order of dependence. Indirectly called by the termination of an
235             instance of this module.
236              
237             =cut
238              
239              
240             sub finalise {
241 1     1 1 4 my ($self, %parameters) = @_;
242 1         2 my $identifications;
243 1         2 do {
244 1         2 $identifications = 0;
245 1         3 for(my $instance = 0; $instance < scalar(@{$self->{IDENTIFICATIONS}}); $instance++) {
  2         25  
246 1 50       8 next if(!defined($self->{'INSTANCE_'.$instance}));
247 0         0 $identifications++;
248 0         0 my $user;
249 0         0 for($user = 0; $user < scalar(@{$self->{IDENTIFICATIONS}}); $user++) {
  0         0  
250 0 0       0 next if($instance == $user);
251 0 0       0 if(defined($self->{'INSTANCE_'.$instance}->{'USER_'.$user})) {
252 0 0       0 next if(undef == $self->{'INSTANCE_'.$instance}->{'USER_'.$user});
253 0 0       0 next if(!defined($self->{'INSTANCE_'.$user}));
254 0         0 last;
255             }
256             }
257 0 0       0 if(scalar(@{$self->{IDENTIFICATIONS}}) == $user) {
  0         0  
258 0         0 $self->{'INSTANCE_'.$instance}->DESTROY();
259 0 0       0 if(defined($self->{'INSTANCE_'.$instance})) {
260 0 0       0 delete $self->{'INSTANCE_'.$instance} if(0 == $self->{'INSTANCE_'.$instance}->{REGISTERED});
261             }
262             }
263             }
264             } while(0 < $identifications);
265             }
266              
267              
268             =head2 identification
269              
270             my $someExample = Some::Example->new();
271             my $objectManager = Anansi::ObjectManager->new();
272             my $identification = $objectManager->identification($someExample);
273             if(defined($identification));
274              
275             my $someExample = Some::Example->new();
276             my $objectManager = Anansi::ObjectManager->new();
277             my $identification, $index;
278             try {
279             $identification = $someExample->{IDENTIFICATION};
280             }
281             $ordinal = $objectManager->identification($identification) if(defined($identification));
282             if(defined($ordinal));
283              
284             =over 4
285              
286             =item self I<(Blessed Hash, Required)>
287              
288             An object of this namespace.
289              
290             =item instance I<(Blessed Hash B String, Optional)>
291              
292             Either a previously registered object or an object's identifying registration
293             number or an object's unique ordinal number as stored internally by this module.
294              
295             =back
296              
297             Assigns an identifying number to a module object instance as required and either
298             returns the identifying number or the unique ordinal number of the module object
299             instance as stored internally by this module.
300              
301             =cut
302              
303              
304             sub identification {
305 2     2 1 2 my ($self, $instance) = @_;
306 2 100       11 if(!defined($instance)) {
    50          
    50          
307 1         159 my ($second, $minute, $hour, $day, $month, $year) = localtime(time);
308 1         4 my $random;
309             my $identification;
310 1         6 do {
311 1         38 $random = int(rand(1000000));
312 1         13 $identification = sprintf("%4d%02d%02d%02d%02d%02d%06d", $year + 1900, $month, $day, $hour, $minute, $second, $random);
313             } while(defined($self->identification($identification)));
314 1         3 return $identification;
315             } elsif(ref($instance) =~ /^(CODE|FORMAT|GLOB|HASH|IO|LVALUE|REF|Regexp|SCALAR|VSTRING)$/i) {
316             } elsif(ref($instance) =~ /^$/) {
317 1 50       4 return if($instance =~ /^\s*$/);
318 1 50       15 return if(!defined($self->{IDENTIFICATIONS}));
319 0 0       0 return if(ref($self->{IDENTIFICATIONS}) !~ /^ARRAY$/i);
320 0         0 for(my $index = 0; $index < scalar(@{$self->{IDENTIFICATIONS}}); $index++) {
  0         0  
321 0 0       0 return $index if($instance == @{$self->{IDENTIFICATIONS}}[$index]);
  0         0  
322             }
323 0 0       0 return if($instance !~ /^\d+$/);
324 0 0       0 return ${$self->{IDENTIFICATIONS}}[$instance] if(0 + $instance < scalar(@{$self->{IDENTIFICATIONS}}));
  0         0  
  0         0  
325             } else {
326 0 0       0 return if(!defined($instance->{IDENTIFICATION}));
327 0 0       0 return if($instance->{IDENTIFICATION} =~ /^\s*$/);
328 0         0 for(my $index = 0; $index < scalar(@{$self->{IDENTIFICATIONS}}); $index++) {
  0         0  
329 0 0       0 return $index if($instance->{IDENTIFICATION} == @{$self->{IDENTIFICATIONS}}[$index]);
  0         0  
330             }
331             }
332 0         0 return;
333             }
334              
335              
336             =head2 initialise
337              
338             package Some::Example;
339              
340             use base qw(Anansi::ObjectManager);
341              
342             sub initialise {
343             my ($self, %parameters) = @_;
344             $self->SUPER::initialise(%parameters);
345             }
346              
347             1;
348              
349             =over 4
350              
351             =item self I<(Blessed Hash, Required)>
352              
353             An object of this namespace.
354              
355             =item parameters I<(Hash, Optional)>
356              
357             Named parameters.
358              
359             =back
360              
361             Performs after creation actions on the first instance object of this module that
362             is created.
363              
364             =cut
365              
366              
367             sub initialise {
368 1     1 1 3 my ($self, %parameters) = @_;
369 1         3 $self->{IDENTIFICATION} = $self->identification();
370 1         4 $self->{IDENTIFICATIONS} = [
371             $self->{IDENTIFICATION}
372             ];
373             }
374              
375              
376             =head2 new
377              
378             my $objectManager = Anansi::ObjectManager->new();
379              
380             =over 4
381              
382             =item class I<(Blessed Hash B String, Required)>
383              
384             Either an object of this namespace or this module's namespace.
385              
386             =item parameters I<(Hash, Optional)>
387              
388             Named parameters.
389              
390             =back
391              
392             Instantiates an object instance of this module, ensuring that the object
393             instance can be interpreted by this module. This object is a singleton so only
394             one object will ever be created at any one time by a Perl script. Subsequent
395             uses of this subroutine will return the existing object.
396              
397             =cut
398              
399              
400             sub new {
401 1     1 1 3 my ($class, %parameters) = @_;
402 1 50       6 return if(ref($class) =~ /^(ARRAY|CODE|FORMAT|GLOB|HASH|IO|LVALUE|REF|Regexp|SCALAR|VSTRING)$/i);
403 1 50       5 $class = ref($class) if(ref($class) !~ /^$/);
404 1 50       4 if(!defined($NAMESPACE)) {
405 1         9 my $self = {
406             NAMESPACE => $class,
407             PACKAGE => __PACKAGE__,
408             };
409 1         2 $NAMESPACE = bless($self, $class);
410 1         5 $NAMESPACE->initialise(%parameters);
411             } else {
412 0         0 $NAMESPACE->reinitialise(%parameters);
413             }
414 1         3 return $NAMESPACE;
415             }
416              
417              
418             =head2 obsolete
419              
420             my $someObject = Some::Example->new();
421             $someObject->{ANOTHER_OBJECT} = Another::Example->new();
422             my $objectManager = Anansi::ObjectManager->new();
423             $objectManager->current(
424             USER => $someObject,
425             USES => $someObject->{ANOTHER_OBJECT},
426             );
427             my $objectManager = Anansi::ObjectManager->new();
428             $objectManager->obsolete(
429             USER => $someObject,
430             USES => $someObject->{ANOTHER_OBJECT},
431             );
432             delete $someObject->{ANOTHER_OBJECT};
433              
434             my $someObject = Some::Example->new();
435             $someObject->{ANOTHER_OBJECT} = Another::Example->new();
436             $someObject->{YET_ANOTHER_OBJECT} = Yet::Another::Example->new();
437             my $objectManager = Anansi::ObjectManager->new();
438             $objectManager->current(
439             USER => $someObject,
440             USES => [$someObject->{ANOTHER_OBJECT}, $someObject->{YET_ANOTHER_OBJECT}],
441             );
442             my $objectManager = Anansi::ObjectManager->new();
443             $objectManager->obsolete(
444             USER => $someObject,
445             USES => [$someObject->{ANOTHER_OBJECT}, $someObject->{YET_ANOTHER_OBJECT}],
446             );
447             delete $someObject->{ANOTHER_OBJECT};
448             delete $someObject->{YET_ANOTHER_OBJECT};
449              
450             =over 4
451              
452             =item self I<(Blessed Hash, Required)>
453              
454             An object of this namespace.
455              
456             =item parameters I<(Hash, Required)>
457              
458             Named parameters.
459              
460             =over 4
461              
462             =item USER I<(Blessed Hash, Required)>
463              
464             The object that has previously needed the I objects to only be garbage
465             collected at some time after it has finished using them and no longer does.
466             This object may be garbage collected at any time after the Perl interpreter has
467             determined that it is no longer in use.
468              
469             =item USES I<(Blessed Hash B Array, Required)>
470              
471             Either an object or an array of objects that the I object has previously
472             needed to only be garbage collected at some time after it has finished using
473             them and now no longer does.
474              
475             =back
476              
477             =back
478              
479             Ensures that module object instances that have previously been tied to an object
480             instance can terminate prior to the termination of the tying object instance.
481             This allows object instances that are no longer required to be cleaned-up early
482             by the perl interpreter garbage collection.
483              
484             =cut
485              
486              
487             sub obsolete {
488 0     0 1 0 my ($self, %parameters) = @_;
489 0 0       0 return if(!defined($parameters{USER}));
490 0 0       0 return if(ref($parameters{USER}) =~ /^(|ARRAY|CODE|FORMAT|GLOB|HASH|IO|LVALUE|REF|Regexp|SCALAR|VSTRING)$/i);
491 0         0 my $user = $parameters{USER};
492 0 0       0 return if(!defined($user->{IDENTIFICATION}));
493 0         0 my $userIndex = $self->identification($user->{IDENTIFICATION});
494 0 0       0 return if(!defined($userIndex));
495 0 0       0 return if(!defined($self->{'INSTANCE_'.$userIndex}));
496 0 0       0 if(!defined($parameters{USES})) {
    0          
    0          
497 0         0 for(my $identification = scalar(@{$self->{IDENTIFICATIONS}}) - 1; 0 < $identification; $identification--) {
  0         0  
498 0 0       0 next if(!defined($self->{'INSTANCE_'.$identification}));
499 0 0       0 if(defined($self->{'INSTANCE_'.$identification}->{'USER_'.$userIndex})) {
500 0 0       0 if(!defined($self->{'INSTANCE_'.$identification}->{PACKAGE})) {
    0          
    0          
501 0         0 $self->unregister($self->{'INSTANCE_'.$identification});
502             } elsif(ref($self->{'INSTANCE_'.$identification}->{PACKAGE}) !~ /^$/) {
503 0         0 $self->unregister($self->{'INSTANCE_'.$identification});
504             } elsif($self->{'INSTANCE_'.$identification}->{PACKAGE} !~ /^Anansi::.*$/) {
505 0         0 $self->unregister($self->{'INSTANCE_'.$identification});
506             }
507 0         0 $self->{'INSTANCE_'.$identification}->DESTROY();
508 0 0       0 if(defined($self->{'INSTANCE_'.$identification})) {
509 0 0       0 delete $self->{'INSTANCE_'.$identification}->{'USER_'.$userIndex} if(defined($self->{'INSTANCE_'.$identification}->{'USER_'.$userIndex}));
510             }
511             }
512             }
513             } elsif(ref($parameters{USES}) =~ /^(|CODE|FORMAT|GLOB|HASH|IO|LVALUE|REF|Regexp|SCALAR|VSTRING)$/i) {
514 0         0 return;
515             } elsif(ref($parameters{USES}) =~ /^ARRAY$/i) {
516 0         0 foreach my $uses (@{$parameters{USES}}) {
  0         0  
517 0 0       0 if(ref($uses) =~ /^(CODE|FORMAT|GLOB|HASH|IO|LVALUE|REF|Regexp|SCALAR|VSTRING)$/i) {
    0          
518 0         0 next;
519             } elsif(ref($uses) =~ /^$/) {
520 0         0 my $usesIndex = $self->identification($uses);
521 0 0       0 next if(!defined($usesIndex));
522 0 0       0 next if(!defined($self->{'INSTANCE_'.$usesIndex}));
523 0 0       0 if(defined($self->{'INSTANCE_'.$usesIndex}->{'USER_'.$userIndex})) {
524 0 0       0 if(!defined($self->{'INSTANCE_'.$usesIndex}->{PACKAGE})) {
    0          
    0          
525 0         0 $self->unregister($self->{'INSTANCE_'.$usesIndex});
526             } elsif(ref($self->{'INSTANCE_'.$usesIndex}->{PACKAGE}) !~ /^$/) {
527 0         0 $self->unregister($self->{'INSTANCE_'.$usesIndex});
528             } elsif($self->{'INSTANCE_'.$usesIndex}->{PACKAGE} !~ /^Anansi::.*$/) {
529 0         0 $self->unregister($self->{'INSTANCE_'.$usesIndex});
530             }
531 0         0 $self->{'INSTANCE_'.$usesIndex}->DESTROY();
532 0 0       0 if(defined($self->{'INSTANCE_'.$usesIndex})) {
533 0 0       0 delete $self->{'INSTANCE_'.$usesIndex}->{'USER_'.$userIndex} if(defined($self->{'INSTANCE_'.$usesIndex}->{'USER_'.$userIndex}));
534             }
535             }
536             } else {
537 0 0       0 next if(!defined($uses->{IDENTIFICATION}));
538 0         0 my $usesIndex = $self->identification($uses->{IDENTIFICATION});
539 0 0       0 next if(!defined($usesIndex));
540 0 0       0 next if(!defined($self->{'INSTANCE_'.$usesIndex}));
541 0 0       0 if(defined($self->{'INSTANCE_'.$usesIndex}->{'USER_'.$userIndex})) {
542 0 0       0 if(!defined($self->{'INSTANCE_'.$usesIndex}->{PACKAGE})) {
    0          
    0          
543 0         0 $self->unregister($self->{'INSTANCE_'.$usesIndex});
544             } elsif(ref($self->{'INSTANCE_'.$usesIndex}->{PACKAGE}) !~ /^$/) {
545 0         0 $self->unregister($self->{'INSTANCE_'.$usesIndex});
546             } elsif($self->{'INSTANCE_'.$usesIndex}->{PACKAGE} !~ /^Anansi::.*$/) {
547 0         0 $self->unregister($self->{'INSTANCE_'.$usesIndex});
548             }
549 0         0 $self->{'INSTANCE_'.$usesIndex}->DESTROY();
550 0 0       0 if(defined($self->{'INSTANCE_'.$usesIndex})) {
551 0 0       0 delete $self->{'INSTANCE_'.$usesIndex}->{'USER_'.$userIndex} if(defined($self->{'INSTANCE_'.$usesIndex}->{'USER_'.$userIndex}));
552             }
553             }
554             }
555             }
556             } else {
557 0         0 my $uses = $parameters{USES};
558 0 0       0 return if(!defined($uses->{IDENTIFICATION}));
559 0         0 my $usesIndex = $self->identification($uses->{IDENTIFICATION});
560 0 0       0 return if(!defined($usesIndex));
561 0 0       0 if(defined($self->{'INSTANCE_'.$usesIndex}->{'USER_'.$userIndex})) {
562 0 0       0 if(!defined($self->{'INSTANCE_'.$usesIndex}->{PACKAGE})) {
    0          
    0          
563 0         0 $self->unregister($self->{'INSTANCE_'.$usesIndex});
564             } elsif(ref($self->{'INSTANCE_'.$usesIndex}->{PACKAGE}) !~ /^$/) {
565 0         0 $self->unregister($self->{'INSTANCE_'.$usesIndex});
566             } elsif($self->{'INSTANCE_'.$usesIndex}->{PACKAGE} !~ /^Anansi::.*$/) {
567 0         0 $self->unregister($self->{'INSTANCE_'.$usesIndex});
568             }
569 0         0 $self->{'INSTANCE_'.$usesIndex}->DESTROY();
570 0 0       0 if(defined($self->{'INSTANCE_'.$usesIndex})) {
571 0 0       0 delete $self->{'INSTANCE_'.$usesIndex}->{'USER_'.$userIndex} if(defined($self->{'INSTANCE_'.$usesIndex}->{'USER_'.$userIndex}));
572             }
573             }
574             }
575             }
576              
577              
578             =head2 old
579              
580             package Some::Example;
581              
582             use base qw(Anansi::ObjectManager);
583              
584             sub old {
585             my ($self, %parameters) = @_;
586             $self->SUPER::old(%parameters);
587             }
588              
589             1;
590              
591             =over 4
592              
593             =item self I<(Blessed Hash, Required)>
594              
595             An object of this namespace.
596              
597             =item parameters I<(Hash, Optional)>
598              
599             Named parameters.
600              
601             =back
602              
603             Performs module object instance clean-up actions.
604              
605             =cut
606              
607              
608             sub old {
609 1     1 1 5 my ($self, %parameters) = @_;
610 1         6 $self->finalise(%parameters);
611             }
612              
613              
614             =head2 register
615              
616             my $someObject = Some::Example->new();
617             my $objectManager = Anansi::ObjectManager->new();
618             $objectManager->register($someObject);
619              
620             =over 4
621              
622             =item self I<(Blessed Hash, Required)>
623              
624             An object of this namespace.
625              
626             =item instance I<(Blessed Hash, Required)>
627              
628             The object to register with this module.
629              
630             =back
631              
632             Ties as required an object instance to this module and increments an internal
633             counter as to how many times the object instance has been tied. This ensure
634             that the perl garbage collection does not remove the object instance from memory
635             until either the object instance is untied or this module has terminated.
636              
637             =cut
638              
639              
640             sub register {
641 0     0 1   my ($self, $instance) = @_;
642 0 0         return 0 if(ref($instance) =~ /^(|ARRAY|CODE|FORMAT|GLOB|HASH|IO|LVALUE|REF|Regexp|SCALAR|VSTRING)$/i);
643 0 0         if(!defined($instance->{IDENTIFICATION})) {
644 0           $instance->{IDENTIFICATION} = $self->identification();
645 0           push(@{$self->{IDENTIFICATIONS}}, $instance->{IDENTIFICATION});
  0            
646             }
647 0           my $instanceIndex = $self->identification($instance);
648 0 0         return 0 if(!defined($instanceIndex));
649 0 0         $instance->{REGISTERED} = 0 if(!defined($instance->{REGISTERED}));
650 0           $instance->{REGISTERED}++;
651 0 0         $self->{'INSTANCE_'.$instanceIndex} = $instance if(!defined($self->{'INSTANCE_'.$instanceIndex}));
652 0           return 1;
653             }
654              
655              
656             =head2 registrations
657              
658             my $someObject = Some::Example->new();
659             my $objectManager = Anansi::ObjectManager->new();
660             $objectManager->register($someObject);
661             if(0 < $objectManager->registrations($someObject));
662              
663             =over 4
664              
665             =item self I<(Blessed Hash, Required)>
666              
667             An object of this namespace.
668              
669             =item instance I<(Blessed Hash, Required)>
670              
671             The object that has previously been registered with this module.
672              
673             =back
674              
675             Determines the number of times an object instance has been tied to this module.
676             If no previous registrations exist then B<0> I<(zero)> will be returned.
677              
678             =cut
679              
680              
681             sub registrations {
682 0     0 1   my ($self, $instance) = @_;
683 0 0         return 0 if(ref($instance) =~ /^(|ARRAY|CODE|FORMAT|GLOB|HASH|IO|LVALUE|REF|Regexp|SCALAR|VSTRING)$/i);
684 0 0         return 0 if(!defined($instance->{IDENTIFICATION}));
685 0           return $instance->{REGISTERED};
686             }
687              
688              
689             =head2 reinitialise
690              
691             package Some::Example;
692              
693             use base qw(Anansi::ObjectManager);
694              
695             sub reinitialise {
696             my ($self, %parameters) = @_;
697             $self->SUPER::reinitialise(%parameters);
698             }
699              
700             1;
701              
702             =over 4
703              
704             =item self I<(Blessed Hash, Required)>
705              
706             An object of this namespace.
707              
708             =item parameters I<(Hash, Optional)>
709              
710             Named parameters.
711              
712             =back
713              
714             Performs additional after creation actions on subsequent instance objects of
715             this module that are created.
716              
717             =cut
718              
719              
720             sub reinitialise {
721 0     0 1   my ($self, %parameters) = @_;
722             }
723              
724              
725             =head2 unregister
726              
727             my $someObject = Some::Example->new();
728             my $objectManager = Anansi::ObjectManager->new();
729             $objectManager->register($someObject);
730             my $objectManager = Anansi::ObjectManager->new();
731             $objectManager->unregister($someObject);
732              
733             =over 4
734              
735             =item self I<(Blessed Hash, Required)>
736              
737             An object of this namespace.
738              
739             =item instance I<(Blessed Hash, Required)>
740              
741             The object that has previously been registered with this module.
742              
743             =back
744              
745             Reduce the number of times an object instance has been tied to this module and
746             remove the tie that inhibits the perl garbage collection from removing the
747             object instance from memory if the object instance is no longer tied.
748              
749             =cut
750              
751              
752             sub unregister {
753 0     0 1   my ($self, $instance) = @_;
754 0 0         return 1 if(!defined($instance->{IDENTIFICATION}));
755 0           my $instanceIndex = $self->identification($instance);
756 0 0         return 1 if(!defined($instanceIndex));
757 0           $instance->{REGISTERED}--;
758 0 0         return 1 if(!defined($self->{'INSTANCE_'.$instanceIndex}));
759 0 0         if(0 == $instance->{REGISTERED}) {
760 0           for(my $identification = 0; $identification < scalar(@{$self->{IDENTIFICATIONS}}); $identification++) {
  0            
761 0 0         next if($instanceIndex == $identification);
762 0 0         next if(!defined($self->{'INSTANCE_'.$identification}));
763 0 0         return 1 if(defined($self->{'INSTANCE_'.$instanceIndex}->{'USER_'.$identification}));
764             }
765 0           delete $self->{'INSTANCE_'.$instanceIndex};
766             }
767 0           return 1;
768             }
769              
770              
771             =head2 user
772              
773             my $someObject = Some::Example->new();
774             $someObject->{ANOTHER_OBJECT} = Another::Example->new();
775             my $objectManager = Anansi::ObjectManager->new();
776             $objectManager->current(
777             USER => $someObject,
778             USES => $someObject->{ANOTHER_OBJECT},
779             );
780             my $userObjects = $objectManager->user($someObject);
781             if(defined($userObjects)) {
782             foreach my $userObject (@{$userObjects}) {
783             }
784             }
785              
786             =over 4
787              
788             =item self I<(Blessed Hash, Required)>
789              
790             An object of this namespace.
791              
792             =item instance I<(Blessed Hash, Required)>
793              
794             Either an object that has not previously been registered with this module or one
795             that has been previously registered.
796              
797             =back
798              
799             Determine the object instances that are made use of by the supplied object
800             I. If the object instance has not previously been registered then it
801             will be. If object instances are found, an array of their unique ordinal
802             numbers as stored internally by this module will be returned otherwise an
803             B will be returned.
804              
805             =cut
806              
807              
808             sub user {
809 0     0 1   my ($self, $instance) = @_;
810 0 0         return if(ref($instance) =~ /^(|ARRAY|CODE|FORMAT|GLOB|HASH|IO|LVALUE|REF|Regexp|SCALAR|VSTRING)$/i);
811 0 0         return if(!defined($instance->{IDENTIFICATION}));
812 0           my $instanceIndex = $self->identification($instance);
813 0 0         return if(!defined($instanceIndex));
814 0 0         return if(!defined($self->{'INSTANCE_'.$instanceIndex}));
815 0           my @identifications;
816 0           for(my $identification = 0; $identification < scalar(@{$self->{IDENTIFICATIONS}}); $identification++) {
  0            
817 0 0         next if($instanceIndex == $identification);
818 0 0         next if(!defined($self->{'INSTANCE_'.$identification}));
819 0 0         push(@identifications, $identification) if(defined($self->{'INSTANCE_'.$identification}->{'USER_'.$instanceIndex}));
820             }
821 0 0         return if(0 == scalar(@identifications));
822 0           return [(@identifications)];
823             }
824              
825              
826             =head2 uses
827              
828             my $someObject = Some::Example->new();
829             my $anotherObject = Another::Example->new();
830             $someObject->{ANOTHER_OBJECT} = $anotherObject;
831             my $objectManager = Anansi::ObjectManager->new();
832             $objectManager->current(
833             USER => $someObject,
834             USES => $someObject->{ANOTHER_OBJECT},
835             );
836             my $usesObjects = $objectManager->uses($anotherObject);
837             if(defined($usesObjects)) {
838             foreach my $usesObject (@{$usesObjects}) {
839             }
840             }
841              
842             =over 4
843              
844             =item self I<(Blessed Hash, Required)>
845              
846             An object of this namespace.
847              
848             =item instance I<(Blessed Hash, Required)>
849              
850             Either an object that has not previously been registered with this module or one
851             that has been previously registered.
852              
853             =back
854              
855             Determine the object instances that make use of the supplied object I.
856             If the object instance has not previously been registered then it will be. If
857             object instances are found, an array of their unique ordinal numbers as stored
858             internally by this module will be returned otherwise an B will be
859             returned.
860              
861             =cut
862              
863              
864             sub uses {
865 0     0 1   my ($self, $instance) = @_;
866 0 0         return if(ref($instance) =~ /^(|ARRAY|CODE|FORMAT|GLOB|HASH|IO|LVALUE|REF|Regexp|SCALAR|VSTRING)$/i);
867 0 0         return if(!defined($instance->{IDENTIFICATION}));
868 0           my $instanceIndex = $self->identification($instance);
869 0 0         return if(!defined($instanceIndex));
870 0 0         return if(!defined($self->{'INSTANCE_'.$instanceIndex}));
871 0           my @identifications;
872 0           for(my $identification = 0; $identification < scalar(@{$self->{IDENTIFICATIONS}}); $identification++) {
  0            
873 0 0         next if($instanceIndex == $identification);
874 0 0         push(@identifications, $identification) if(defined($self->{'INSTANCE_'.$instanceIndex}->{'USER_'.$identification}));
875             }
876 0 0         return if(0 == scalar(@identifications));
877 0           return [(@identifications)];
878             }
879              
880              
881             =head1 NOTES
882              
883             This module is designed to make it simple, easy and quite fast to code your
884             design in perl. If for any reason you feel that it doesn't achieve these goals
885             then please let me know. I am here to help. All constructive criticisms are
886             also welcomed.
887              
888             As this module is not intended to be directly implemented by an end user
889             subroutine, as a measure to improve process speed, relatively few validation and
890             verification tests are performed. As a result, if you have any problems
891             implementing this module from within your own module, please contact me. If
892             this lack of testing becomes a problem in the future, I will modify this module
893             to implement the necessary tests. Thank you for your continued support and
894             understanding.
895              
896             =cut
897              
898              
899             END {
900 1 50   1   11 $OBJECTMANAGER->old() if(defined($OBJECTMANAGER));
901             }
902              
903              
904             =head1 AUTHOR
905              
906             Kevin Treleaven treleaven I net>
907              
908             =cut
909              
910              
911             1;