File Coverage

blib/lib/Anansi/ObjectManager.pm
Criterion Covered Total %
statement 31 460 6.7
branch 11 390 2.8
condition n/a
subroutine 6 14 42.8
pod 13 13 100.0
total 61 877 6.9


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