File Coverage

blib/lib/Acme/Voodoo.pm
Criterion Covered Total %
statement 34 75 45.3
branch 4 24 16.6
condition 1 6 16.6
subroutine 8 12 66.6
pod 4 4 100.0
total 51 121 42.1


line stmt bran cond sub pod time code
1             package Acme::Voodoo;
2              
3 1     1   798 use strict;
  1         2  
  1         40  
4 1     1   5 use warnings;
  1         3  
  1         41  
5 1     1   18 use Carp qw( croak );
  1         2  
  1         144  
6              
7             our $VERSION = 0.3;
8              
9             my %dolls = ();
10             my %deads = ();
11             my %zombies = ();
12             my $dreamTime = 0;
13              
14             =head1 NAME
15              
16             Acme::Voodoo - Do bad stuff to your objects
17              
18             =head1 SYNOPSIS
19              
20             use Acme::Voodoo;
21             my $voodoo = Acme::Voodoo->new( 'CGI' );
22            
23             print ref( $voodoo ); ## prints Acme::Voodoo::Doll_1
24             print $voodoo->header(); ## same as calling CGI::header()
25              
26             @pins = $voodoo->pins(); ## get a list of methods you can call
27              
28             $voodoo->zombie(); ## make our program sleep for a while
29             ## the next time a method is called
30              
31             $voodoo->kill(); ## or make our program die the next
32             ## time it is called
33              
34             =head1 ABSTRACT
35              
36             Voodoo is an Afro-Caribbean religion that mixed practices from the Fon,
37             the Nago, the Ibos, Dahomeans, Congos, Senegalese, Haussars, Caplauous,
38             Mondungues, Madinge, Angolese, Libyans, Ethiopians and the Malgaches.
39             With a bit of Roman Catholicism thrown in for good measure. This melange was
40             brought about by the enforced immigration of African slaves into Haiti during
41             the period of European colonizaltion of Hispaniola. The colonists thought that a divided group of different tribes would be easier to enslave; but little
42             did they know that the tribes had a common thread.
43              
44             In reality the actual religion is called "Vodun", while "Voodoo" is a largely
45             imaginary religion created by Hollywood movies. Vodun priests can be male
46             (houngan) and female (mambo) and confine their activites to "white" magic.
47             However caplatas (also known as bokors) do practice acts of evil sorcery,
48             which is sometimes referred to "left-handed Vodun".
49              
50             Acme::Voodoo is mostly "left handed" and somewhat "Hollywood-ish" but can
51             bring a bit of spice to your programs. You can cast fairly simple spells on
52             your program to make it hard to understand, or to make it die a horrible
53             death. If you would like to add a spell please email me a patch. Or send it
54             via astral-projection. Acme::Voodoo is essentially an experiment in
55             symbol tables gone horribly wrong.
56              
57             =head1 METHODS
58              
59             =head2 new()
60              
61             Creates a voodoo doll object. You must pass the namespace of your subject. If
62             your subject isn't within spell distance (the class can't be found) an
63             exception will be thrown. Otherwise you get back your doll, an
64             Acme::Voodoo::Doll object.
65              
66             use Acme::Voodoo;
67             my $doll = Acme::Voodoo->new( 'CGI' );
68             print $doll->header();
69              
70             =cut
71              
72             sub new {
73              
74             ## uhoh, voodoo
75 1     1   7 no strict;
  1         4  
  1         425  
76              
77             ## figure out what class we are targeting
78 1     1 1 500 my ( $voodooClass, $targetClass, @args ) = @_;
79 1     1   1629665 eval "use $targetClass";
  1         28267  
  1         9  
  1         64  
80 1 50 33     50 croak "I can't find $targetClass to put a spell on" if !$targetClass or $@;
81              
82             ## if the class doesn't have a new constructor we can't cast our spell
83 1         7 croak "curses, $targetClass is resilient to my spell"
84 1 50       2 if ! exists( ${ "${targetClass}::" }{ 'new' } );
85              
86             ## determine a new namespace for our voodoo doll
87 1         4 my $dollNum = scalar( keys( %dolls ) );
88 1         4 my $dollClass = "Acme::Voodoo::Doll_$dollNum";
89              
90             ## go through our target namespace and copy non subroutines
91             ## into our Acme::Voodoo::Doll_X namespace
92 1         2 while ( ($k,$v) = each %{ "${targetClass}::" } ) {
  29         154  
93 29 100       48 if ( !defined(&{$v}) ) { ${ "${dollClass}::" }{ $k } = $v; }
  29         280  
  11         12  
  11         49  
94             }
95              
96             ## create an instance of our target class, and stash it away
97 0           my $instance = &{ "${targetClass}::new" }( @args );
  0            
98 0           $dolls{ $dollClass } = $instance;
99              
100             ## create the appropriate type of reference
101 0           my $ref;
102 0 0         if ( $instance =~ /HASH/ ) { $ref = {}; }
  0 0          
    0          
103 0           elsif ( $instance =~ /ARRAY/ ) { $ref = []; }
104             elsif ( $instance =~ /GLOB/ ) {
105 0           croak "glob objects are currently resistant to our voodoo spells!";
106             }
107 0           $doll = bless $ref, $dollClass;
108              
109             ## make our voodoo doll namespace inherit the AUTLOADER
110             ## from the Acme::Voodoo namespace so we can trap method calls
111 0           push( @{ "${dollClass}::ISA" }, 'Acme::Voodoo' );
  0            
112              
113 0           return( $doll );
114              
115             }
116              
117             =head2 pins()
118              
119             Pass this function your voodoo doll and you'll get back a list of pins you
120             can use on your doll.
121              
122             my @pins = $doll->pins();
123              
124             =cut
125              
126             sub pins {
127 0     0 1   my $doll = shift;
128 0           my $dollClass = ref( $dolls{ ref($doll) } );
129 0           my @methods = ();
130 0 0         return( () ) if !$dollClass;
131              
132 1     1   4 no strict;
  1         2  
  1         307  
133 0           while ( my($k,$v) = each( %{ "${dollClass}::" } ) ) {
  0            
134 0 0         push( @methods, $k ) if defined &{ $v };
  0            
135             }
136              
137 0           return( @methods );
138             }
139              
140             =head2 zombie()
141              
142             A method to turn your object into a zombie. The next method call on the object
143             will cause your program to go into limbo for an unpredictable amount of time.
144             When it wakes up, it will do what you asked it to do, and will feel fine from
145             then on, having no memory of what happened. If you know how long you want
146             your target to go to sleep for, pass the number of seconds in.
147              
148             =cut
149              
150             sub zombie {
151 0     0 1   my ( $self, $sleep ) = @_;
152 0           $zombies{ ref($self) } = 1;
153 0 0         $dreamTime = $sleep if $sleep;
154 0           return(1);
155             }
156              
157             =head2 kill()
158              
159             When you kill your doll the next time someone calls a method on it it will
160             cause your program to die a horrible and painful death.
161              
162             $doll->kill();
163             $doll->method(); ## arrrrrggggghhhh!!
164              
165             =cut
166              
167             sub kill {
168 0     0 1   my $self = shift;
169 0           $deads{ ref($self) } = 1;
170 0           return( 1 );
171             }
172              
173             =head1 AUTHOR
174              
175             Ed Summers, Eehs@pobox.comE
176              
177             =head1 COPYRIGHT AND LICENSE
178              
179             Copyright 2002 by Ed Summers
180              
181             This library is free software; you can redistribute it and/or modify
182             it under the same terms as Perl itself. Just be sure not to use it for
183             anything important.
184              
185             =cut
186              
187             sub AUTOLOAD {
188              
189 0     0     my ($doll,@args) = @_;
190 0           our $AUTOLOAD;
191              
192             ## if we're dead, then we're gonna die
193 0 0         croak( "arrrghgghg, an evil curse has struck me down!\n" )
194             if $deads{ ref($doll) };
195              
196             ## if we are a zombie, go to sleep for a random amount of time
197             ## and then wake up remembering nothing
198 0 0         if ( $zombies{ ref($doll) } ) {
199 0           print STDERR "I feel as if I'm walking into a strange dream\n";
200 0   0       sleep( $dreamTime || int( rand(100) ) * 10 );
201 0           $zombies{ ref($doll) } = undef;
202             }
203              
204             ## strip namespace off of method
205 0           my ($method) = ( $AUTOLOAD =~ /.*::(.*)$/ );
206              
207             ## our real object
208 0           my $object = $dolls{ ref($doll) };
209 0           my $class = ref( $object );
210            
211 1     1   6 no strict;
  1         1  
  1         118  
212 0 0         return( undef ) if $method eq 'DESTROY';
213              
214             ## call the method on the real object, with the right args
215             ## note: we will return the return value of our method call
216 0           &{ "${class}::${method}" }( $object, @args );
  0            
217              
218             }
219              
220             ## no more voodoo
221              
222             1;