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   1486 use 5.018;
  87         287  
4              
5 87     87   481 use strict;
  87         173  
  87         2060  
6 87     87   458 use warnings;
  87         209  
  87         2682  
7              
8 87     87   58294 use Venus;
  87         238  
  87         560  
9              
10 87     87   579 use base 'Venus::Core';
  87         184  
  87         28566  
11              
12             # METHODS
13              
14             sub attr {
15 3     3 1 18 my ($self, $name) = @_;
16              
17 3 50       12 return 0 if !$name;
18              
19 3         10 my $data = {map +($_,$_), @{$self->attrs}};
  3         10  
20              
21 3 100       24 return $data->{$name} ? true : false;
22             }
23              
24             sub attrs {
25 637     637 1 1269 my ($self) = @_;
26              
27 637 100       1645 if ($self->{attrs}) {
28 1         5 return $self->{attrs};
29             }
30              
31 636         1164 my $name = $self->{name};
32 636         1501 my @attrs = attrs_resolver($name);
33              
34 636         1172 for my $base (@{$self->bases}) {
  636         1575  
35 2435         3842 push @attrs, attrs_resolver($base);
36             }
37              
38 636         1158 for my $role (@{$self->roles}) {
  636         1388  
39 11113         16651 push @attrs, attrs_resolver($role);
40             }
41              
42 636         1093 my %seen;
43 636   50     4482 my $results = $self->{attrs} ||= [grep !$seen{$_}++, @attrs];
44              
45 636 100       3057 return wantarray ? (@$results) : $results;
46             }
47              
48             sub attrs_resolver {
49 14187     14187 0 19494 my ($name) = @_;
50              
51 87     87   732 no strict 'refs';
  87         228  
  87         2981  
52 87     87   522 no warnings 'once';
  87         288  
  87         36777  
53              
54 14187 100 100     16308 if (${"${name}::META"} && $${"${name}::META"}{ATTR}) {
  14187         37284  
  12915         35869  
55             return (sort {
56 2569         3153 $${"${name}::META"}{ATTR}{$a}[0] <=> $${"${name}::META"}{ATTR}{$b}[0]
  2569         4948  
  2569         6999  
57 1221         1690 } keys %{$${"${name}::META"}{ATTR}});
  1221         1647  
  1221         5683  
58             }
59             else {
60 12966         21411 return ();
61             }
62             }
63              
64             sub base {
65 2     2 1 5 my ($self, $name) = @_;
66              
67 2 50       6 return 0 if !$name;
68              
69 2         3 my $data = {map +($_,$_), @{$self->bases}};
  2         6  
70              
71 2 100       14 return $data->{$name} ? true : false;
72             }
73              
74             sub bases {
75 4139     4139 1 7012 my ($self) = @_;
76              
77 4139 100       9664 if ($self->{bases}) {
78 1438         3644 return $self->{bases};
79             }
80              
81 2701         4661 my $name = $self->{name};
82 2701         5818 my @bases = bases_resolver($name);
83              
84 2701         5696 for my $base (@bases) {
85 17151         25576 push @bases, bases_resolver($base);
86             }
87              
88 2701         4607 my %seen;
89 2701   50     23496 my $results = $self->{bases} ||= [grep !$seen{$_}++, @bases];
90              
91 2701 50       11980 return wantarray ? (@$results) : $results;
92             }
93              
94             sub bases_resolver {
95 19854     19854 0 26633 my ($name) = @_;
96              
97 87     87   717 no strict 'refs';
  87         209  
  87         8458  
98              
99 19854         22365 return (@{"${name}::ISA"});
  19854         60800  
100             }
101              
102             sub data {
103 1     1 1 4 my ($self) = @_;
104              
105 1         3 my $name = $self->{name};
106              
107 87     87   698 no strict 'refs';
  87         189  
  87         21256  
108              
109 1         2 return ${"${name}::META"};
  1         7  
110             }
111              
112             sub emit {
113 1     1 1 5 my ($self, $hook, @args) = @_;
114              
115 1         3 my $name = $self->{name};
116              
117 1         4 $hook = uc $hook;
118              
119 1         5 return $name->$hook(@args);
120             }
121              
122             sub find {
123 4     4 1 18 my ($self, $type, $name) = @_;
124              
125 4 100       15 return if !$type;
126 3 50       10 return if !$name;
127              
128 3         4 my $configs;
129              
130 3         8 for my $source (qw(roles bases mixins self)) {
131 6         13 $configs = $self->search($source, $type, $name);
132 6 100       21 last if @$configs;
133             }
134              
135 3 50       35 return $configs ? $configs->[0] : undef;
136             }
137              
138             sub local {
139 6     6 1 22 my ($self, $type) = @_;
140              
141 6 50       18 return if !$type;
142              
143 6         14 my $name = $self->{name};
144              
145 87     87   690 no strict 'refs';
  87         216  
  87         32458  
146              
147 6 50       37 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         26  
152              
153 6 50       49 return wantarray ? (@$results) : $results;
154             }
155              
156             sub mixin {
157 2     2 1 5 my ($self, $name) = @_;
158              
159 2 50       6 return 0 if !$name;
160              
161 2         3 my $data = {map +($_,$_), @{$self->mixins}};
  2         4  
162              
163 2 100       15 return $data->{$name} ? true : false;
164             }
165              
166             sub mixins {
167 13345     13345 1 26260 my ($self) = @_;
168              
169 13345 100       35628 if ($self->{mixins}) {
170 12544         35252 return $self->{mixins};
171             }
172              
173 801         1911 my $name = $self->{name};
174 801         2326 my @mixins = mixins_resolver($name);
175              
176 801         2058 for my $mixin (@mixins) {
177 37         75 push @mixins, mixins_resolver($mixin);
178             }
179              
180 801         1337 for my $base (@{$self->bases}) {
  801         2145  
181 2930         4799 push @mixins, mixins_resolver($base);
182             }
183              
184 801         1605 my %seen;
185 801   50     4239 my $results = $self->{mixins} ||= [grep !$seen{$_}++, @mixins];
186              
187 801 50       3370 return wantarray ? (@$results) : $results;
188             }
189              
190             sub mixins_resolver {
191 3807     3807 0 6178 my ($name) = @_;
192              
193 87     87   725 no strict 'refs';
  87         241  
  87         40717  
194              
195 3807 100 100     4619 if (${"${name}::META"} && $${"${name}::META"}{MIXIN}) {
  3807         12455  
  2149         7725  
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         66 } keys %{$${"${name}::META"}{MIXIN}});
  38         55  
  38         198  
199             }
200             else {
201 3769         7428 return ();
202             }
203             }
204              
205             sub new {
206 2733     2733 1 7017 my ($self, @args) = @_;
207              
208 2733         8470 return $self->BLESS(@args);
209             }
210              
211             sub role {
212 634     634 1 1500 my ($self, $name) = @_;
213              
214 634 50       1493 return 0 if !$name;
215              
216 634         997 my $data = {map +($_,$_), @{$self->roles}};
  634         1522  
217              
218 634 100       3662 return $data->{$name} ? true : false;
219             }
220              
221             sub roles {
222 28459     28459 1 50740 my ($self) = @_;
223              
224 28459 100       64451 if ($self->{roles}) {
225 25764         143882 return $self->{roles};
226             }
227              
228 2695         4549 my $name = $self->{name};
229 2695         6093 my @roles = roles_resolver($name);
230              
231 2695         5939 for my $role (@roles) {
232 6169         9307 push @roles, roles_resolver($role);
233             }
234              
235 2695         4073 for my $base (@{$self->bases}) {
  2695         6273  
236 9382         15222 push @roles, roles_resolver($base);
237             }
238              
239 2695         4515 my %seen;
240 2695   50     31166 my $results = $self->{roles} ||= [grep !$seen{$_}++, @roles];
241              
242 2695 100       19706 return wantarray ? (@$results) : $results;
243             }
244              
245             sub roles_resolver {
246 59659     59659 0 84672 my ($name) = @_;
247              
248 87     87   732 no strict 'refs';
  87         245  
  87         3701  
249 87     87   563 no warnings 'once';
  87         245  
  87         18937  
250              
251 59659 100 100     66360 if (${"${name}::META"} && $${"${name}::META"}{ROLE}) {
  59659         174814  
  54008         149015  
252             return (map +($_, roles_resolver($_)), sort {
253 100060         110570 $${"${name}::META"}{ROLE}{$a}[0] <=> $${"${name}::META"}{ROLE}{$b}[0]
  100060         174639  
  100060         188203  
254 5792         7730 } keys %{$${"${name}::META"}{ROLE}});
  5792         7028  
  5792         31114  
255             }
256             else {
257 53867         117485 return ();
258             }
259             }
260              
261             sub search {
262 10     10 1 25 my ($self, $from, $type, $name) = @_;
263              
264 10 100       24 return if !$from;
265 9 50       27 return if !$type;
266 9 50       18 return if !$name;
267              
268 87     87   739 no strict 'refs';
  87         204  
  87         47787  
269              
270 9         19 my @configs;
271             my @sources;
272              
273 9 100       39 if (lc($from) eq 'bases') {
    100          
    100          
274 1         3 @sources = bases_resolver($self->{name});
275             }
276             elsif (lc($from) eq 'roles') {
277 4         10 @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         19 for my $source (@sources) {
287 14 100       33 if (lc($type) eq 'sub') {
288 10 100       12 if (*{"${source}::${name}"}{"CODE"}) {
  10         43  
289 4         8 push @configs, [$source, [1, [*{"${source}::${name}"}{"CODE"}]]];
  4         21  
290             }
291             }
292             else {
293 4 100       7 if ($${"${source}::META"}{uc($type)}{$name}) {
  4         22  
294 2         5 push @configs, [$source, $${"${source}::META"}{uc($type)}{$name}];
  2         10  
295             }
296             }
297             }
298              
299 9         17 my $results = [@configs];
300              
301 9 50       45 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         3 my $data = {map +($_,$_), @{$self->subs}};
  2         9  
310              
311 2 100       19 return $data->{$name} ? true : false;
312             }
313              
314             sub subs {
315 3     3 1 7 my ($self) = @_;
316              
317 3 50       8 if ($self->{subs}) {
318 0         0 return $self->{subs};
319             }
320              
321 3         6 my $name = $self->{name};
322 3         8 my @subs = subs_resolver($name);
323              
324 3         10 for my $base (@{$self->bases}) {
  3         10  
325 9         21 push @subs, subs_resolver($base);
326             }
327              
328 3         5 my %seen;
329 3   50     77 my $results = $self->{subs} ||= [grep !$seen{$_}++, @subs];
330              
331 3 50       71 return wantarray ? (@$results) : $results;
332             }
333              
334             sub subs_resolver {
335 13     13 0 25 my ($name) = @_;
336              
337 87     87   727 no strict 'refs';
  87         257  
  87         24207  
338              
339             return (
340 311         646 grep *{"${name}::$_"}{"CODE"},
341 13         20 grep /^[_a-zA-Z]\w*$/, keys %{"${name}::"}
  13         202  
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