File Coverage

blib/lib/Venus/Meta.pm
Criterion Covered Total %
statement 214 218 98.1
branch 63 80 78.7
condition 14 19 73.6
subroutine 36 36 100.0
pod 16 21 76.1
total 343 374 91.7


line stmt bran cond sub pod time code
1             package Venus::Meta;
2              
3 87     87   1454 use 5.018;
  87         287  
4              
5 87     87   465 use strict;
  87         212  
  87         2060  
6 87     87   458 use warnings;
  87         222  
  87         2442  
7              
8 87     87   58343 use Venus;
  87         306  
  87         545  
9              
10 87     87   573 use base 'Venus::Core';
  87         172  
  87         26491  
11              
12             # METHODS
13              
14             sub attr {
15 3     3 1 10 my ($self, $name) = @_;
16              
17 3 50       11 return 0 if !$name;
18              
19 3         6 my $data = {map +($_,$_), @{$self->attrs}};
  3         11  
20              
21 3 100       24 return $data->{$name} ? true : false;
22             }
23              
24             sub attrs {
25 637     637 1 1152 my ($self) = @_;
26              
27 637 100       1619 if ($self->{attrs}) {
28 1         6 return $self->{attrs};
29             }
30              
31 636         1040 my $name = $self->{name};
32 636         1424 my @attrs = attrs_resolver($name);
33              
34 636         1263 for my $base (@{$self->bases}) {
  636         1499  
35 2435         3752 push @attrs, attrs_resolver($base);
36             }
37              
38 636         983 for my $role (@{$self->roles}) {
  636         1456  
39 11113         15565 push @attrs, attrs_resolver($role);
40             }
41              
42 636         1253 my %seen;
43 636   50     4310 my $results = $self->{attrs} ||= [grep !$seen{$_}++, @attrs];
44              
45 636 100       2996 return wantarray ? (@$results) : $results;
46             }
47              
48             sub attrs_resolver {
49 14187     14187 0 19469 my ($name) = @_;
50              
51 87     87   668 no strict 'refs';
  87         182  
  87         3270  
52 87     87   541 no warnings 'once';
  87         220  
  87         35324  
53              
54 14187 100 100     15682 if (${"${name}::META"} && $${"${name}::META"}{ATTR}) {
  14187         36692  
  12915         35214  
55             return (sort {
56 2512         3162 $${"${name}::META"}{ATTR}{$a}[0] <=> $${"${name}::META"}{ATTR}{$b}[0]
  2512         4880  
  2512         6870  
57 1221         1658 } keys %{$${"${name}::META"}{ATTR}});
  1221         1486  
  1221         5664  
58             }
59             else {
60 12966         20951 return ();
61             }
62             }
63              
64             sub base {
65 2     2 1 7 my ($self, $name) = @_;
66              
67 2 50       6 return 0 if !$name;
68              
69 2         6 my $data = {map +($_,$_), @{$self->bases}};
  2         7  
70              
71 2 100       14 return $data->{$name} ? true : false;
72             }
73              
74             sub bases {
75 4153     4153 1 7095 my ($self) = @_;
76              
77 4153 100       9244 if ($self->{bases}) {
78 1440         3619 return $self->{bases};
79             }
80              
81 2713         4344 my $name = $self->{name};
82 2713         5715 my @bases = bases_resolver($name);
83              
84 2713         5745 for my $base (@bases) {
85 17175         25715 push @bases, bases_resolver($base);
86             }
87              
88 2713         4656 my %seen;
89 2713   50     23114 my $results = $self->{bases} ||= [grep !$seen{$_}++, @bases];
90              
91 2713 50       12251 return wantarray ? (@$results) : $results;
92             }
93              
94             sub bases_resolver {
95 19890     19890 0 26934 my ($name) = @_;
96              
97 87     87   706 no strict 'refs';
  87         213  
  87         8310  
98              
99 19890         22353 return (@{"${name}::ISA"});
  19890         60420  
100             }
101              
102             sub data {
103 1     1 1 3 my ($self) = @_;
104              
105 1         3 my $name = $self->{name};
106              
107 87     87   655 no strict 'refs';
  87         200  
  87         21458  
108              
109 1         3 return ${"${name}::META"};
  1         7  
110             }
111              
112             sub emit {
113 1     1 1 4 my ($self, $hook, @args) = @_;
114              
115 1         3 my $name = $self->{name};
116              
117 1         3 $hook = uc $hook;
118              
119 1         5 return $name->$hook(@args);
120             }
121              
122             sub find {
123 4     4 1 13 my ($self, $type, $name) = @_;
124              
125 4 100       17 return if !$type;
126 3 50       10 return if !$name;
127              
128 3         4 my $configs;
129              
130 3         9 for my $source (qw(roles bases mixins self)) {
131 6         19 $configs = $self->search($source, $type, $name);
132 6 100       14 last if @$configs;
133             }
134              
135 3 50       26 return $configs ? $configs->[0] : undef;
136             }
137              
138             sub local {
139 6     6 1 21 my ($self, $type) = @_;
140              
141 6 50       20 return if !$type;
142              
143 6         12 my $name = $self->{name};
144              
145 87     87   650 no strict 'refs';
  87         188  
  87         32051  
146              
147 6 50       34 return if !int grep $type eq $_, qw(attrs bases mixins roles subs);
148              
149 6         19 my $function = "${type}_resolver";
150              
151 6         11 my $results = [&{"${function}"}($name)];
  6         24  
152              
153 6 50       53 return wantarray ? (@$results) : $results;
154             }
155              
156             sub mixin {
157 2     2 1 6 my ($self, $name) = @_;
158              
159 2 50       6 return 0 if !$name;
160              
161 2         4 my $data = {map +($_,$_), @{$self->mixins}};
  2         9  
162              
163 2 100       15 return $data->{$name} ? true : false;
164             }
165              
166             sub mixins {
167 13353     13353 1 25648 my ($self) = @_;
168              
169 13353 100       35101 if ($self->{mixins}) {
170 12547         34555 return $self->{mixins};
171             }
172              
173 806         1968 my $name = $self->{name};
174 806         2259 my @mixins = mixins_resolver($name);
175              
176 806         1957 for my $mixin (@mixins) {
177 37         77 push @mixins, mixins_resolver($mixin);
178             }
179              
180 806         1330 for my $base (@{$self->bases}) {
  806         2134  
181 2940         4814 push @mixins, mixins_resolver($base);
182             }
183              
184 806         1701 my %seen;
185 806   50     4279 my $results = $self->{mixins} ||= [grep !$seen{$_}++, @mixins];
186              
187 806 50       3351 return wantarray ? (@$results) : $results;
188             }
189              
190             sub mixins_resolver {
191 3822     3822 0 6130 my ($name) = @_;
192              
193 87     87   754 no strict 'refs';
  87         192  
  87         41355  
194              
195 3822 100 100     4764 if (${"${name}::META"} && $${"${name}::META"}{MIXIN}) {
  3822         12084  
  2154         7705  
196             return (map +($_, mixins_resolver($_)), sort {
197 0         0 $${"${name}::META"}{MIXIN}{$a}[0] <=> $${"${name}::META"}{MIXIN}{$b}[0]
  0         0  
  0         0  
198 38         72 } keys %{$${"${name}::META"}{MIXIN}});
  38         75  
  38         208  
199             }
200             else {
201 3784         7778 return ();
202             }
203             }
204              
205             sub new {
206 2747     2747 1 7320 my ($self, @args) = @_;
207              
208 2747         8000 return $self->BLESS(@args);
209             }
210              
211             sub role {
212 635     635 1 1598 my ($self, $name) = @_;
213              
214 635 50       1411 return 0 if !$name;
215              
216 635         1040 my $data = {map +($_,$_), @{$self->roles}};
  635         1554  
217              
218 635 100       4100 return $data->{$name} ? true : false;
219             }
220              
221             sub roles {
222 28476     28476 1 50831 my ($self) = @_;
223              
224 28476 100       66130 if ($self->{roles}) {
225 25772         136739 return $self->{roles};
226             }
227              
228 2704         4675 my $name = $self->{name};
229 2704         6417 my @roles = roles_resolver($name);
230              
231 2704         6123 for my $role (@roles) {
232 6175         9546 push @roles, roles_resolver($role);
233             }
234              
235 2704         3895 for my $base (@{$self->bases}) {
  2704         6386  
236 9400         16792 push @roles, roles_resolver($base);
237             }
238              
239 2704         4835 my %seen;
240 2704   50     30241 my $results = $self->{roles} ||= [grep !$seen{$_}++, @roles];
241              
242 2704 100       19335 return wantarray ? (@$results) : $results;
243             }
244              
245             sub roles_resolver {
246 59698     59698 0 84736 my ($name) = @_;
247              
248 87     87   694 no strict 'refs';
  87         218  
  87         3280  
249 87     87   516 no warnings 'once';
  87         198  
  87         19101  
250              
251 59698 100 100     65203 if (${"${name}::META"} && $${"${name}::META"}{ROLE}) {
  59698         171325  
  54029         147294  
252             return (map +($_, roles_resolver($_)), sort {
253 101485         113443 $${"${name}::META"}{ROLE}{$a}[0] <=> $${"${name}::META"}{ROLE}{$b}[0]
  101485         174727  
  101485         189731  
254 5798         7757 } keys %{$${"${name}::META"}{ROLE}});
  5798         7052  
  5798         30835  
255             }
256             else {
257 53900         115810 return ();
258             }
259             }
260              
261             sub search {
262 10     10 1 38 my ($self, $from, $type, $name) = @_;
263              
264 10 100       36 return if !$from;
265 9 50       24 return if !$type;
266 9 50       21 return if !$name;
267              
268 87     87   737 no strict 'refs';
  87         235  
  87         47108  
269              
270 9         18 my @configs;
271             my @sources;
272              
273 9 100       48 if (lc($from) eq 'bases') {
    100          
    100          
274 1         4 @sources = bases_resolver($self->{name});
275             }
276             elsif (lc($from) eq 'roles') {
277 4         12 @sources = roles_resolver($self->{name});
278             }
279             elsif (lc($from) eq 'mixins') {
280 1         4 @sources = mixins_resolver($self->{name});
281             }
282             else {
283 3         9 @sources = ($self->{name});
284             }
285              
286 9         22 for my $source (@sources) {
287 14 100       39 if (lc($type) eq 'sub') {
288 10 100       15 if (*{"${source}::${name}"}{"CODE"}) {
  10         57  
289 4         11 push @configs, [$source, [1, [*{"${source}::${name}"}{"CODE"}]]];
  4         23  
290             }
291             }
292             else {
293 4 100       6 if ($${"${source}::META"}{uc($type)}{$name}) {
  4         21  
294 2         4 push @configs, [$source, $${"${source}::META"}{uc($type)}{$name}];
  2         11  
295             }
296             }
297             }
298              
299 9         22 my $results = [@configs];
300              
301 9 50       41 return wantarray ? (@$results) : $results;
302             }
303              
304             sub sub {
305 2     2 1 7 my ($self, $name) = @_;
306              
307 2 50       9 return 0 if !$name;
308              
309 2         6 my $data = {map +($_,$_), @{$self->subs}};
  2         8  
310              
311 2 100       21 return $data->{$name} ? true : false;
312             }
313              
314             sub subs {
315 3     3 1 9 my ($self) = @_;
316              
317 3 50       11 if ($self->{subs}) {
318 0         0 return $self->{subs};
319             }
320              
321 3         7 my $name = $self->{name};
322 3         13 my @subs = subs_resolver($name);
323              
324 3         11 for my $base (@{$self->bases}) {
  3         9  
325 9         19 push @subs, subs_resolver($base);
326             }
327              
328 3         7 my %seen;
329 3   50     87 my $results = $self->{subs} ||= [grep !$seen{$_}++, @subs];
330              
331 3 50       70 return wantarray ? (@$results) : $results;
332             }
333              
334             sub subs_resolver {
335 13     13 0 23 my ($name) = @_;
336              
337 87     87   686 no strict 'refs';
  87         213  
  87         25406  
338              
339             return (
340 311         620 grep *{"${name}::$_"}{"CODE"},
341 13         20 grep /^[_a-zA-Z]\w*$/, keys %{"${name}::"}
  13         203  
342             );
343             }
344              
345             1;
346              
347              
348              
349             =head1 NAME
350              
351             Venus::Meta - Class Metadata
352              
353             =cut
354              
355             =head1 ABSTRACT
356              
357             Class Metadata for Perl 5
358              
359             =cut
360              
361             =head1 SYNOPSIS
362              
363             package Person;
364              
365             use Venus::Class;
366              
367             attr 'fname';
368             attr 'lname';
369              
370             package Identity;
371              
372             use Venus::Role;
373              
374             attr 'id';
375             attr 'login';
376             attr 'password';
377              
378             sub EXPORT {
379             # explicitly declare routines to be consumed
380             ['id', 'login', 'password']
381             }
382              
383             package Authenticable;
384              
385             use Venus::Role;
386              
387             sub authenticate {
388             return true;
389             }
390              
391             sub AUDIT {
392             my ($self, $from) = @_;
393             # ensure the caller has a login and password when consumed
394             die "${from} missing the login attribute" if !$from->can('login');
395             die "${from} missing the password attribute" if !$from->can('password');
396             }
397              
398             sub EXPORT {
399             # explicitly declare routines to be consumed
400             ['authenticate']
401             }
402              
403             package Novice;
404              
405             use Venus::Mixin;
406              
407             sub points {
408             100
409             }
410              
411             package User;
412              
413             use Venus::Class 'attr', 'base', 'mixin', 'test', 'with';
414              
415             base 'Person';
416              
417             with 'Identity';
418              
419             mixin 'Novice';
420              
421             attr 'email';
422              
423             test 'Authenticable';
424              
425             sub valid {
426             my ($self) = @_;
427             return $self->login && $self->password ? true : false;
428             }
429              
430             package main;
431              
432             my $user = User->new(
433             fname => 'Elliot',
434             lname => 'Alderson',
435             );
436              
437             my $meta = $user->meta;
438              
439             # bless({name => 'User'}, 'Venus::Meta')
440              
441             =cut
442              
443             =head1 DESCRIPTION
444              
445             This package provides configuration information for L derived classes,
446             roles, and interfaces.
447              
448             =cut
449              
450             =head1 METHODS
451              
452             This package provides the following methods:
453              
454             =cut
455              
456             =head2 attr
457              
458             attr(Str $name) (Bool)
459              
460             The attr method returns true or false if the package referenced has the
461             attribute accessor named.
462              
463             I>
464              
465             =over 4
466              
467             =item attr example 1
468              
469             # given: synopsis
470              
471             package main;
472              
473             my $attr = $meta->attr('email');
474              
475             # 1
476              
477             =back
478              
479             =over 4
480              
481             =item attr example 2
482              
483             # given: synopsis
484              
485             package main;
486              
487             my $attr = $meta->attr('username');
488              
489             # 0
490              
491             =back
492              
493             =cut
494              
495             =head2 attrs
496              
497             attrs() (ArrayRef)
498              
499             The attrs method returns all of the attributes composed into the package
500             referenced.
501              
502             I>
503              
504             =over 4
505              
506             =item attrs example 1
507              
508             # given: synopsis
509              
510             package main;
511              
512             my $attrs = $meta->attrs;
513              
514             # [
515             # 'email',
516             # 'fname',
517             # 'id',
518             # 'lname',
519             # 'login',
520             # 'password',
521             # ]
522              
523             =back
524              
525             =cut
526              
527             =head2 base
528              
529             base(Str $name) (Bool)
530              
531             The base method returns true or false if the package referenced has inherited
532             the package named.
533              
534             I>
535              
536             =over 4
537              
538             =item base example 1
539              
540             # given: synopsis
541              
542             package main;
543              
544             my $base = $meta->base('Person');
545              
546             # 1
547              
548             =back
549              
550             =over 4
551              
552             =item base example 2
553              
554             # given: synopsis
555              
556             package main;
557              
558             my $base = $meta->base('Student');
559              
560             # 0
561              
562             =back
563              
564             =cut
565              
566             =head2 bases
567              
568             bases() (ArrayRef)
569              
570             The bases method returns returns all of the packages inherited by the package
571             referenced.
572              
573             I>
574              
575             =over 4
576              
577             =item bases example 1
578              
579             # given: synopsis
580              
581             package main;
582              
583             my $bases = $meta->bases;
584              
585             # [
586             # 'Person',
587             # 'Venus::Core::Class',
588             # 'Venus::Core',
589             # ]
590              
591             =back
592              
593             =cut
594              
595             =head2 data
596              
597             data() (HashRef)
598              
599             The data method returns a data structure representing the shallow configuration
600             for the package referenced.
601              
602             I>
603              
604             =over 4
605              
606             =item data example 1
607              
608             # given: synopsis
609              
610             package main;
611              
612             my $data = $meta->data;
613              
614             # {
615             # 'ATTR' => {
616             # 'email' => [
617             # 'email'
618             # ]
619             # },
620             # 'BASE' => {
621             # 'Person' => [
622             # 'Person'
623             # ]
624             # },
625             # 'ROLE' => {
626             # 'Authenticable' => [
627             # 'Authenticable'
628             # ],
629             # 'Identity' => [
630             # 'Identity'
631             # ]
632             # }
633             # }
634              
635             =back
636              
637             =cut
638              
639             =head2 emit
640              
641             emit(Str $name, Any @args) (Any)
642              
643             The emit method invokes the lifecycle hook specified on the underlying package
644             and returns the result.
645              
646             I>
647              
648             =over 4
649              
650             =item emit example 1
651              
652             # given: synopsis
653              
654             package main;
655              
656             my $result = $meta->emit('attr', 'mname');
657              
658             # "User"
659              
660             =back
661              
662             =cut
663              
664             =head2 find
665              
666             find(Str $type, Str $name) (Tuple[Str,Tuple[Int,ArrayRef]])
667              
668             The find method finds and returns the first configuration for the property type
669             specified. This method uses the L method to search C, C,
670             C, and the source package, in the order listed. The "property type" can
671             be any one of C, C, C, or C.
672              
673             I>
674              
675             =over 4
676              
677             =item find example 1
678              
679             # given: synopsis
680              
681             package main;
682              
683             my $find = $meta->find;
684              
685             # ()
686              
687             =back
688              
689             =over 4
690              
691             =item find example 2
692              
693             # given: synopsis
694              
695             package main;
696              
697             my $find = $meta->find('attr', 'id');
698              
699             # ['Identity', [ 1, ['id']]]
700              
701             =back
702              
703             =over 4
704              
705             =item find example 3
706              
707             # given: synopsis
708              
709             package main;
710              
711             my $find = $meta->find('sub', 'valid');
712              
713             # ['User', [1, [sub {...}]]]
714              
715             =back
716              
717             =over 4
718              
719             =item find example 4
720              
721             # given: synopsis
722              
723             package main;
724              
725             my $find = $meta->find('sub', 'authenticate');
726              
727             # ['Authenticable', [1, [sub {...}]]]
728              
729             =back
730              
731             =cut
732              
733             =head2 local
734              
735             local(Str $type) (ArrayRef)
736              
737             The local method returns the names of properties defined in the package
738             directly (not inherited) for the property type specified. The C<$type> provided
739             can be either C, C, C, or C.
740              
741             I>
742              
743             =over 4
744              
745             =item local example 1
746              
747             # given: synopsis
748              
749             package main;
750              
751             my $attrs = $meta->local('attrs');
752              
753             # ['email']
754              
755             =back
756              
757             =over 4
758              
759             =item local example 2
760              
761             # given: synopsis
762              
763             package main;
764              
765             my $bases = $meta->local('bases');
766              
767             # ['Person', 'Venus::Core::Class']
768              
769             =back
770              
771             =over 4
772              
773             =item local example 3
774              
775             # given: synopsis
776              
777             package main;
778              
779             my $roles = $meta->local('roles');
780              
781             # ['Identity', 'Authenticable']
782              
783             =back
784              
785             =over 4
786              
787             =item local example 4
788              
789             # given: synopsis
790              
791             package main;
792              
793             my $subs = $meta->local('subs');
794              
795             # [
796             # 'attr',
797             # 'authenticate',
798             # 'base',
799             # 'email',
800             # 'false',
801             # 'id',
802             # 'login',
803             # 'password',
804             # 'test',
805             # 'true',
806             # 'valid',
807             # 'with',
808             # ]
809              
810             =back
811              
812             =cut
813              
814             =head2 mixin
815              
816             mixin(Str $name) (Bool)
817              
818             The mixin method returns true or false if the package referenced has consumed
819             the mixin named.
820              
821             I>
822              
823             =over 4
824              
825             =item mixin example 1
826              
827             # given: synopsis
828              
829             package main;
830              
831             my $mixin = $meta->mixin('Novice');
832              
833             # 1
834              
835             =back
836              
837             =over 4
838              
839             =item mixin example 2
840              
841             # given: synopsis
842              
843             package main;
844              
845             my $mixin = $meta->mixin('Intermediate');
846              
847             # 0
848              
849             =back
850              
851             =cut
852              
853             =head2 mixins
854              
855             mixins() (ArrayRef)
856              
857             The mixins method returns all of the mixins composed into the package
858             referenced.
859              
860             I>
861              
862             =over 4
863              
864             =item mixins example 1
865              
866             # given: synopsis
867              
868             package main;
869              
870             my $mixins = $meta->mixins;
871              
872             # [
873             # 'Novice',
874             # ]
875              
876             =back
877              
878             =cut
879              
880             =head2 new
881              
882             new(Any %args | HashRef $args) (Object)
883              
884             The new method returns a new instance of this package.
885              
886             I>
887              
888             =over 4
889              
890             =item new example 1
891              
892             # given: synopsis
893              
894             package main;
895              
896             $meta = Venus::Meta->new(name => 'User');
897              
898             # bless({name => 'User'}, 'Venus::Meta')
899              
900             =back
901              
902             =over 4
903              
904             =item new example 2
905              
906             # given: synopsis
907              
908             package main;
909              
910             $meta = Venus::Meta->new({name => 'User'});
911              
912             # bless({name => 'User'}, 'Venus::Meta')
913              
914             =back
915              
916             =cut
917              
918             =head2 role
919              
920             role(Str $name) (Bool)
921              
922             The role method returns true or false if the package referenced has consumed
923             the role named.
924              
925             I>
926              
927             =over 4
928              
929             =item role example 1
930              
931             # given: synopsis
932              
933             package main;
934              
935             my $role = $meta->role('Identity');
936              
937             # 1
938              
939             =back
940              
941             =over 4
942              
943             =item role example 2
944              
945             # given: synopsis
946              
947             package main;
948              
949             my $role = $meta->role('Builder');
950              
951             # 0
952              
953             =back
954              
955             =cut
956              
957             =head2 roles
958              
959             roles() (ArrayRef)
960              
961             The roles method returns all of the roles composed into the package referenced.
962              
963             I>
964              
965             =over 4
966              
967             =item roles example 1
968              
969             # given: synopsis
970              
971             package main;
972              
973             my $roles = $meta->roles;
974              
975             # [
976             # 'Identity',
977             # 'Authenticable'
978             # ]
979              
980             =back
981              
982             =cut
983              
984             =head2 search
985              
986             search(Str $from, Str $type, Str $name) (ArrayRef[Tuple[Str,Tuple[Int,ArrayRef]]])
987              
988             The search method searches the source specified and returns the configurations
989             for the property type specified. The source can be any one of C,
990             C, C, or C for the source package. The "property type" can
991             be any one of C, C, C, or C.
992              
993             I>
994              
995             =over 4
996              
997             =item search example 1
998              
999             # given: synopsis
1000              
1001             package main;
1002              
1003             my $search = $meta->search;
1004              
1005             # ()
1006              
1007             =back
1008              
1009             =over 4
1010              
1011             =item search example 2
1012              
1013             # given: synopsis
1014              
1015             package main;
1016              
1017             my $search = $meta->search('roles', 'attr', 'id');
1018              
1019             # [['Identity', [ 1, ['id']]]]
1020              
1021             =back
1022              
1023             =over 4
1024              
1025             =item search example 3
1026              
1027             # given: synopsis
1028              
1029             package main;
1030              
1031             my $search = $meta->search('self', 'sub', 'valid');
1032              
1033             # [['User', [1, [sub {...}]]]]
1034              
1035             =back
1036              
1037             =over 4
1038              
1039             =item search example 4
1040              
1041             # given: synopsis
1042              
1043             package main;
1044              
1045             my $search = $meta->search('self', 'sub', 'authenticate');
1046              
1047             # [['User', [1, [sub {...}]]]]
1048              
1049             =back
1050              
1051             =cut
1052              
1053             =head2 sub
1054              
1055             sub(Str $name) (Bool)
1056              
1057             The sub method returns true or false if the package referenced has the
1058             subroutine named on the package directly, or any of its superclasses.
1059              
1060             I>
1061              
1062             =over 4
1063              
1064             =item sub example 1
1065              
1066             # given: synopsis
1067              
1068             package main;
1069              
1070             my $sub = $meta->sub('authenticate');
1071              
1072             # 1
1073              
1074             =back
1075              
1076             =over 4
1077              
1078             =item sub example 2
1079              
1080             # given: synopsis
1081              
1082             package main;
1083              
1084             my $sub = $meta->sub('authorize');
1085              
1086             # 0
1087              
1088             =back
1089              
1090             =cut
1091              
1092             =head2 subs
1093              
1094             subs() (ArrayRef)
1095              
1096             The subs method returns all of the subroutines composed into the package
1097             referenced.
1098              
1099             I>
1100              
1101             =over 4
1102              
1103             =item subs example 1
1104              
1105             # given: synopsis
1106              
1107             package main;
1108              
1109             my $subs = $meta->subs;
1110              
1111             # [
1112             # 'attr', ...,
1113             # 'base',
1114             # 'email',
1115             # 'false',
1116             # 'fname', ...,
1117             # 'id',
1118             # 'lname',
1119             # 'login',
1120             # 'new', ...,
1121             # 'role',
1122             # 'test',
1123             # 'true',
1124             # 'with', ...,
1125             # ]
1126              
1127             =back
1128              
1129             =cut
1130              
1131             =head1 AUTHORS
1132              
1133             Awncorp, C
1134              
1135             =cut
1136              
1137             =head1 LICENSE
1138              
1139             Copyright (C) 2000, Al Newkirk.
1140              
1141             This program is free software, you can redistribute it and/or modify it under
1142             the terms of the Apache license version 2.0.
1143              
1144             =cut