File Coverage

blib/lib/Mars/Class.pm
Criterion Covered Total %
statement 88 88 100.0
branch 16 16 100.0
condition n/a
subroutine 35 35 100.0
pod 5 5 100.0
total 144 144 100.0


line stmt bran cond sub pod time code
1             package Mars::Class;
2              
3 3     9   4156 use 5.018;
  3         9  
4              
5 3     6   13 use strict;
  3         3  
  3         54  
6 3     3   11 use warnings;
  3         3  
  3         190  
7              
8             # IMPORT
9              
10             sub import {
11 35     35   22409 my ($self, @args) = @_;
12              
13 35         56 my $from = caller;
14              
15 35         1122 require Mars::Kind::Class;
16              
17 3     3   24 no strict 'refs';
  3         5  
  3         97  
18 3     3   19 no warnings 'redefine';
  3         21  
  3         164  
19 3     3   14 no warnings 'once';
  3         4  
  3         2009  
20              
21 35         52 @{"${from}::ISA"} = 'Mars::Kind::Class';
  35         520  
22              
23 35 100       98 if (!*{"${from}::attr"}{"CODE"}) {
  35         142  
24 11     15   49 *{"${from}::attr"} = sub {@_ = ($from, @_); goto \&attr};
  11     15   30  
  15     12   68  
  15     6   37  
25             }
26 35 100       45 if (!*{"${from}::base"}{"CODE"}) {
  35         83  
27 11     5   32 *{"${from}::base"} = sub {@_ = ($from, @_); goto \&base};
  11     5   23  
  5     3   20  
  5         13  
28             }
29 35 100       44 if (!*{"${from}::false"}{"CODE"}) {
  35         79  
30 11     5   22 *{"${from}::false"} = sub {require Mars; Mars::false()};
  11         23  
  5         727  
  5         15  
31             }
32 35 100       37 if (!*{"${from}::from"}{"CODE"}) {
  35         75  
33 11     2   36 *{"${from}::from"} = sub {@_ = ($from, @_); goto \&from};
  11     2   21  
  2     2   10  
  2         7  
34             }
35 35 100       44 if (!*{"${from}::role"}{"CODE"}) {
  35         67  
36 11     4   32 *{"${from}::role"} = sub {@_ = ($from, @_); goto \&role};
  11     4   19  
  4     2   21  
  4         14  
37             }
38 35 100       40 if (!*{"${from}::test"}{"CODE"}) {
  35         77  
39 11     7   41 *{"${from}::test"} = sub {@_ = ($from, @_); goto \&test};
  11     7   21  
  7         39  
  7         17  
40             }
41 35 100       37 if (!*{"${from}::true"}{"CODE"}) {
  35         88  
42 11     4   23 *{"${from}::true"} = sub {require Mars; Mars::true()};
  11     4   21  
  4     4   24  
  4     4   13  
43             }
44 35 100       36 if (!*{"${from}::with"}{"CODE"}) {
  35         76  
45 11     8   28 *{"${from}::with"} = sub {@_ = ($from, @_); goto \&test};
  11     8   21  
  8     7   36  
  8         22  
46             }
47              
48 35         49 ${"${from}::META"} = {};
  35         79  
49              
50 35         1636 return $self;
51             }
52              
53             sub attr {
54 15     15 1 30 my ($from, @args) = @_;
55              
56 15         92 $from->ATTR(@args);
57              
58 15         331 return $from;
59             }
60              
61             sub base {
62 5     5 1 10 my ($from, @args) = @_;
63              
64 5         23 $from->BASE(@args);
65              
66 5         66 return $from;
67             }
68              
69             sub from {
70 2     2 1 5 my ($from, @args) = @_;
71              
72 2         12 $from->FROM(@args);
73              
74 2         15 return $from;
75             }
76              
77             sub role {
78 4     4 1 8 my ($from, @args) = @_;
79              
80 4         26 $from->ROLE(@args);
81              
82 4         34 return $from;
83             }
84              
85             sub test {
86 15     15 1 28 my ($from, @args) = @_;
87              
88 15         67 $from->TEST(@args);
89              
90 13         109 return $from;
91             }
92              
93             1;
94              
95              
96              
97             =head1 NAME
98              
99             Mars::Class - Class Declaration
100              
101             =cut
102              
103             =head1 ABSTRACT
104              
105             Class Declaration for Perl 5
106              
107             =cut
108              
109             =head1 SYNOPSIS
110              
111             package Person;
112              
113             use Mars::Class;
114              
115             attr 'fname';
116             attr 'lname';
117              
118             package Identity;
119              
120             use Mars::Role;
121              
122             attr 'id';
123             attr 'login';
124             attr 'password';
125              
126             sub EXPORT {
127             # explicitly declare routines to be consumed
128             ['id', 'login', 'password']
129             }
130              
131             package Authenticable;
132              
133             use Mars::Role;
134              
135             sub authenticate {
136             return true;
137             }
138              
139             sub AUDIT {
140             my ($self, $from) = @_;
141             # ensure the caller has a login and password when consumed
142             die "${from} missing the login attribute" if !$from->can('login');
143             die "${from} missing the password attribute" if !$from->can('password');
144             }
145              
146             sub EXPORT {
147             # explicitly declare routines to be consumed
148             ['authenticate']
149             }
150              
151             package User;
152              
153             use Mars::Class;
154              
155             base 'Person';
156              
157             with 'Identity';
158              
159             attr 'email';
160              
161             test 'Authenticable';
162              
163             sub valid {
164             my ($self) = @_;
165             return $self->login && $self->password ? true : false;
166             }
167              
168             package main;
169              
170             my $user = User->new(
171             fname => 'Elliot',
172             lname => 'Alderson',
173             );
174              
175             # bless({fname => 'Elliot', lname => 'Alderson'}, 'User')
176              
177             =cut
178              
179             =head1 DESCRIPTION
180              
181             This package provides a class builder which when used causes the consumer to
182             inherit from L which provides object construction and
183             lifecycle L.
184              
185             =cut
186              
187             =head1 FUNCTIONS
188              
189             This package provides the following functions:
190              
191             =cut
192              
193             =head2 attr
194              
195             attr(Str $name) (Str)
196              
197             The attr function creates attribute accessors for the calling package. This
198             function is always exported unless a routine of the same name already exists.
199              
200             I>
201              
202             =over 4
203              
204             =item attr example 1
205              
206             package Example;
207              
208             use Mars::Class;
209              
210             attr 'name';
211              
212             # "Example"
213              
214             =back
215              
216             =cut
217              
218             =head2 base
219              
220             base(Str $name) (Str)
221              
222             The base function registers one or more base classes for the calling package.
223             This function is always exported unless a routine of the same name already
224             exists.
225              
226             I>
227              
228             =over 4
229              
230             =item base example 1
231              
232             package Entity;
233              
234             use Mars::Class;
235              
236             sub output {
237             return;
238             }
239              
240             package Example;
241              
242             use Mars::Class;
243              
244             base 'Entity';
245              
246             # "Example"
247              
248             =back
249              
250             =cut
251              
252             =head2 false
253              
254             false() (Bool)
255              
256             The false function returns a falsy boolean value which is designed to be
257             practically indistinguishable from the conventional numerical C<0> value. This
258             function is always exported unless a routine of the same name already exists.
259              
260             I>
261              
262             =over 4
263              
264             =item false example 1
265              
266             package Example;
267              
268             use Mars::Class;
269              
270             my $false = false;
271              
272             # 0
273              
274             =back
275              
276             =over 4
277              
278             =item false example 2
279              
280             package Example;
281              
282             use Mars::Class;
283              
284             my $true = !false;
285              
286             # 1
287              
288             =back
289              
290             =cut
291              
292             =head2 from
293              
294             from(Str $name) (Str)
295              
296             The from function registers one or more base classes for the calling package
297             and performs an L<"audit"|Mars::Kind/AUDIT>. This function is always exported
298             unless a routine of the same name already exists.
299              
300             I>
301              
302             =over 4
303              
304             =item from example 1
305              
306             package Entity;
307              
308             use Mars::Class;
309              
310             sub AUDIT {
311             my ($self, $from) = @_;
312             die "Missing startup" if !$from->can('startup');
313             die "Missing shutdown" if !$from->can('shutdown');
314             }
315              
316             package Example;
317              
318             use Mars::Class;
319              
320             attr 'startup';
321             attr 'shutdown';
322              
323             from 'Entity';
324              
325             # "Example"
326              
327             =back
328              
329             =cut
330              
331             =head2 role
332              
333             role(Str $name) (Str)
334              
335             The role function registers and consumes roles for the calling package. This
336             function is always exported unless a routine of the same name already exists.
337              
338             I>
339              
340             =over 4
341              
342             =item role example 1
343              
344             package Ability;
345              
346             use Mars::Role;
347              
348             sub action {
349             return;
350             }
351              
352             package Example;
353              
354             use Mars::Class;
355              
356             role 'Ability';
357              
358             # "Example"
359              
360             =back
361              
362             =over 4
363              
364             =item role example 2
365              
366             package Ability;
367              
368             use Mars::Role;
369              
370             sub action {
371             return;
372             }
373              
374             sub EXPORT {
375             return ['action'];
376             }
377              
378             package Example;
379              
380             use Mars::Class;
381              
382             role 'Ability';
383              
384             # "Example"
385              
386             =back
387              
388             =cut
389              
390             =head2 test
391              
392             test(Str $name) (Str)
393              
394             The test function registers and consumes roles for the calling package and
395             performs an L<"audit"|Mars::Kind/AUDIT>, effectively allowing a role to act as
396             an interface. This function is always exported unless a routine of the same
397             name already exists.
398              
399             I>
400              
401             =over 4
402              
403             =item test example 1
404              
405             package Actual;
406              
407             use Mars::Role;
408              
409             package Example;
410              
411             use Mars::Class;
412              
413             test 'Actual';
414              
415             # "Example"
416              
417             =back
418              
419             =over 4
420              
421             =item test example 2
422              
423             package Actual;
424              
425             use Mars::Role;
426              
427             sub AUDIT {
428             die "Example is not an 'actual' thing" if $_[1]->isa('Example');
429             }
430              
431             package Example;
432              
433             use Mars::Class;
434              
435             test 'Actual';
436              
437             # "Example"
438              
439             =back
440              
441             =cut
442              
443             =head2 true
444              
445             true() (Bool)
446              
447             The true function returns a truthy boolean value which is designed to be
448             practically indistinguishable from the conventional numerical C<1> value. This
449             function is always exported unless a routine of the same name already exists.
450              
451             I>
452              
453             =over 4
454              
455             =item true example 1
456              
457             package Example;
458              
459             use Mars::Class;
460              
461             my $true = true;
462              
463             # 1
464              
465             =back
466              
467             =over 4
468              
469             =item true example 2
470              
471             package Example;
472              
473             use Mars::Class;
474              
475             my $false = !true;
476              
477             # 0
478              
479             =back
480              
481             =cut
482              
483             =head2 with
484              
485             with(Str $name) (Str)
486              
487             The with function registers and consumes roles for the calling package. This
488             function is an alias of the L function and will perform an
489             L<"audit"|Mars::Kind/AUDIT> if present. This function is always exported unless
490             a routine of the same name already exists.
491              
492             I>
493              
494             =over 4
495              
496             =item with example 1
497              
498             package Understanding;
499              
500             use Mars::Role;
501              
502             sub knowledge {
503             return;
504             }
505              
506             package Example;
507              
508             use Mars::Class;
509              
510             with 'Understanding';
511              
512             # "Example"
513              
514             =back
515              
516             =over 4
517              
518             =item with example 2
519              
520             package Understanding;
521              
522             use Mars::Role;
523              
524             sub knowledge {
525             return;
526             }
527              
528             sub EXPORT {
529             return ['knowledge'];
530             }
531              
532             package Example;
533              
534             use Mars::Class;
535              
536             with 'Understanding';
537              
538             # "Example"
539              
540             =back
541              
542             =cut
543              
544             =head1 AUTHORS
545              
546             Awncorp, C
547              
548             =cut