File Coverage

blib/lib/Class/Prototyped/Mixin.pm
Criterion Covered Total %
statement 33 35 94.2
branch 3 4 75.0
condition n/a
subroutine 8 8 100.0
pod 1 1 100.0
total 45 48 93.7


line stmt bran cond sub pod time code
1             package Class::Prototyped::Mixin;
2 3     3   71837 use strict;
  3         6  
  3         121  
3 3     3   16 use warnings;
  3         6  
  3         110  
4              
5 3     3   16 use Carp qw(cluck);
  3         10  
  3         267  
6 3     3   4140 use Class::Prototyped;
  3         36614  
  3         31  
7              
8             BEGIN {
9 3     3   163 use Exporter ();
  3         6  
  3         64  
10 3     3   53 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  3         7  
  3         413  
11 3     3   8 $VERSION = 3.00_00 ;
12 3         51 @ISA = qw(Exporter);
13             #Give a hoot don't pollute, do not export more than needed by default
14 3         6 @EXPORT = qw();
15 3         8 @EXPORT_OK = qw(mixin);
16 3         451 %EXPORT_TAGS = ();
17             }
18              
19             =head1 NAME
20              
21             Class::Prototyped::Mixin - Mixin Support for Class::Prototyped
22              
23             =head1 SYNOPSIS
24              
25             =head2 Usage one: whip up a class and toss it in a scalar
26              
27             package HelloWorld;
28              
29             sub hello {
30             my ($self, $age) = @_;
31             return "Hello World! I am $age years old"
32             }
33              
34              
35             package HelloWorld::Uppercase;
36             use base qw(Class::Prototyped);
37              
38             __PACKAGE__->reflect->addSlot(
39             [qw(hello superable)] => sub {
40             my $self = shift;
41             my $ret = $self->reflect->super('hello', @_);
42             uc $ret
43             }
44             );
45              
46              
47             package HelloWorld::Bold;
48             use base qw(Class::Prototyped);
49              
50             __PACKAGE__->reflect->addSlot(
51             [qw(hello superable)] => sub {
52             my $self = shift;
53             my $ret = $self->reflect->super('hello', @_);
54             "$ret";
55             }
56             );
57              
58            
59             package HelloWorld::Italic;
60             use base qw(Class::Prototyped);
61              
62             __PACKAGE__->reflect->addSlot(
63             [qw(hello superable)] => sub {
64             my $self = shift;
65             my $ret = $self->reflect->super('hello', @_);
66             "$ret";
67             }
68             );
69              
70             # script.pl - now the whipping begins
71             use Class::Prototyped::Mixin qw(mixin);
72             my $runtime = mixin(
73             'HelloWorld' => 'HelloWorld::Uppercase', 'HelloWorld::Italic'
74             );
75              
76             print $runtime->hello(74);
77             HELLO WORLD! I AM 74 YEARS OLD
78              
79             =head2 Usage two: create hierarchy and install in a Class::Prototyped package
80              
81             package CompileTime;
82             use Class::Prototyped::Mixin qw(mixin);
83              
84             my $uclass = mixin(
85             'HelloWorld' => 'HelloWorld::Uppercase', 'HelloWorld::Bold'
86             );
87              
88             __PACKAGE__->reflect->addSlot(
89             '*' => $uclass
90             );
91              
92              
93             # script.pl
94             use CompileTime;
95              
96             print CompileTime->hello(88);
97             HELLO WORLD! I AM 88 YEARS OLD
98              
99             =head1 DESCRIPTION
100              
101             This module aids prototyped-based object programming in Perl by
102             making it easy to layer functionality on base functionality
103             via a collection of mixin classes. The SYNOPSIS is admittedly easier done
104             via a C or some other pure functional approach. However, the case for
105             intelligent, "performant" mixins is argued strongly here:
106             L
107              
108             To date, the Mixin contributions to CPAN use class-based OOP,
109             with L being perhaps the
110             most complete and best documented.
111             This module is one of a series
112             designed to show the flexibility, simplicity
113             and power of prototyped-based object programming.
114              
115             The reason I wish to address object-oriented design concerns in
116             prototype-based object-oriented programming is that it is simple, flexible
117             and seems to involve less confusion than I see evolving with Perl
118             class-based oop. For awhile there was interest in roles. Now there is
119             interest in traits. And there has always been a long-standing interest
120             in mixins, decoration, and delegation.
121              
122             I cringe at the thought of trying to get all of these technologies to
123             meld in a large project. I cringe equally at those who talk and do not
124             do: The last thing that is necessary is for me to SAY that
125             prototyped-based oop can address real-world concerns yet not
126             DEMONSTRATE.
127              
128              
129             =head1 AUTHOR
130              
131             Terrence Brannon
132             CPAN ID: TBONE
133             metaperl.com
134             metaperl@gmail.com
135             http://www.metaperl.com
136              
137             =head1 SOURCES
138              
139             Distributed on CPAN.
140              
141             CVS access is via:
142              
143             cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/sw-design login
144              
145             cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/sw-design co -P cpmixin
146              
147              
148              
149              
150             =head1 COPYRIGHT
151              
152             This program is free software; you can redistribute
153             it and/or modify it under the same terms as Perl itself.
154              
155             The full text of the license can be found in the
156             LICENSE file included with this module.
157              
158              
159             =head1 SEE ALSO
160              
161             =over 4
162              
163             =item * L
164              
165             =back
166              
167             =head1 METHODS
168              
169             =head2 mixin
170              
171             Usage : Class::Prototyped::Mixin::mixin($base, $derived, $derived_two, ..)
172             Purpose : Dynamically build an object with the specified inheritance
173             Returns : a Class::Prototyped object
174             Argument : a list of classes, starting from the root class and moving
175             down the hierarchy
176             Throws : Returns undef if at least 2 classes are not passed in for mixing
177             Comment : This is a sample subroutine header.
178             : It is polite to include more pod and fewer comments.
179              
180             =cut
181              
182             #################### subroutine header end ####################
183              
184              
185             sub mixin {
186 2 50   2 1 4302 unless (@_ >= 2) {
187 0         0 cluck 'at least 2 classes required for mixing';
188 0         0 return;
189             }
190            
191 2         6 my $base = shift;
192 2         4 my @derived;
193             {
194 2         3 push @derived , (shift)->clone;
  4         38  
195 4         1051 $derived[$#derived]->reflect->addSlot('*' => $base);
196              
197 4 100       543 if (@_) {
198 2         5 $base = $derived[$#derived];
199 2         5 redo;
200             }
201              
202             }
203              
204 2         9 $derived[$#derived];
205              
206             }
207              
208              
209              
210              
211              
212              
213             1;
214              
215