File Coverage

blib/lib/Tangence/Meta/Class.pm
Criterion Covered Total %
statement 77 79 97.4
branch 5 10 50.0
condition 7 17 41.1
subroutine 17 18 94.4
pod 15 15 100.0
total 121 139 87.0


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2011-2022 -- leonerd@leonerd.org.uk
5              
6 15     15   171 use v5.26;
  15         52  
7 15     15   83 use Object::Pad 0.66 ':experimental(init_expr)';
  15         178  
  15         76  
8              
9             package Tangence::Meta::Class 0.30;
10             class Tangence::Meta::Class :strict(params);
11              
12 15     15   5751 use Carp;
  15         44  
  15         33270  
13              
14             =head1 NAME
15              
16             C - structure representing one C class
17              
18             =head1 DESCRIPTION
19              
20             This data structure object stores information about one L class.
21             Once constructed and defined, such objects are immutable.
22              
23             =cut
24              
25             =head1 CONSTRUCTOR
26              
27             =cut
28              
29             =head2 new
30              
31             $class = Tangence::Meta::Class->new( name => $name )
32              
33             Returns a new instance representing the given name.
34              
35             =cut
36              
37 602     602 1 2415 field $name :param :reader;
  602         3839  
38 0     0 1 0 field $defined :reader { 0 };
  0         0  
39              
40             field @superclasses;
41             field %methods;
42             field %events;
43             field %properties;
44              
45             =head2 define
46              
47             $class->define( %args )
48              
49             Provides a definition for the class.
50              
51             =over 8
52              
53             =item methods => HASH
54              
55             =item events => HASH
56              
57             =item properties => HASH
58              
59             Optional HASH references containing metadata about methods, events and
60             properties, as instances of L,
61             L or L.
62              
63             =item superclasses => ARRAY
64              
65             Optional ARRAY reference containing superclasses as
66             C references.
67              
68             =back
69              
70             =cut
71              
72 61         106 method define ( %args )
  61         227  
  61         95  
73 61     61 1 208 {
74 61 50       168 $defined and croak "Cannot define $name twice";
75              
76 61         272 $defined++;
77 61   50     137 @superclasses = @{ delete $args{superclasses} // [] };
  61         250  
78 61   50     174 %methods = %{ delete $args{methods} // {} };
  61         299  
79 61   50     158 %events = %{ delete $args{events} // {} };
  61         273  
80 61   50     111 %properties = %{ delete $args{properties} // {} };
  61         408  
81             }
82              
83             =head1 ACCESSORS
84              
85             =cut
86              
87             =head2 defined
88              
89             $defined = $class->defined
90              
91             Returns true if a definintion for the class has been provided using C.
92              
93             =cut
94              
95             =head2 name
96              
97             $name = $class->name
98              
99             Returns the name of the class
100              
101             =cut
102              
103             =head2 perlname
104              
105             $perlname = $class->perlname
106              
107             Returns the perl name of the class. This will be the Tangence name, with dots
108             replaced by double colons (C<::>).
109              
110             =cut
111              
112             method perlname
113 571     571 1 1042 {
114 571         1170 ( my $perlname = $self->name ) =~ s{\.}{::}g; # s///rg in 5.14
115 571         2770 return $perlname;
116             }
117              
118             =head2 direct_superclasses
119              
120             @superclasses = $class->direct_superclasses
121              
122             Return the direct superclasses in a list of C
123             references.
124              
125             =cut
126              
127             method direct_superclasses
128 21     21 1 64 {
129 21 50       72 $defined or croak "$name is not yet defined";
130 21         69 return @superclasses;
131             }
132              
133             =head2 direct_methods
134              
135             $methods = $class->direct_methods
136              
137             Return the methods that this class directly defines (rather than inheriting
138             from superclasses) as a HASH reference mapping names to
139             L instances.
140              
141             =cut
142              
143             method direct_methods
144 53     53 1 149 {
145 53 50       145 $defined or croak "$name is not yet defined";
146 53         341 return { %methods };
147             }
148              
149             =head2 direct_events
150              
151             $events = $class->direct_events
152              
153             Return the events that this class directly defines (rather than inheriting
154             from superclasses) as a HASH reference mapping names to
155             L instances.
156              
157             =cut
158              
159             method direct_events
160 150     150 1 331 {
161 150 50       384 $defined or croak "$name is not yet defined";
162 150         619 return { %events };
163             }
164              
165             =head2 direct_properties
166              
167             $properties = $class->direct_properties
168              
169             Return the properties that this class directly defines (rather than inheriting
170             from superclasses) as a HASH reference mapping names to
171             L instances.
172              
173             =cut
174              
175             method direct_properties
176 821     821 1 1800 {
177 821 50       1526 $defined or croak "$name is not yet defined";
178 821         3947 return { %properties };
179             }
180              
181             =head1 AGGREGATE ACCESSORS
182              
183             The following accessors inspect the full inheritance tree of this class and
184             all its superclasses
185              
186             =cut
187              
188             =head2 superclasses
189              
190             @superclasses = $class->superclasses
191              
192             Return all the superclasses in a list of unique C
193             references.
194              
195             =cut
196              
197             method superclasses
198 627     627 1 1165 {
199             # This algorithm doesn't have to be particularly good, C3 or whatever.
200             # We're not really forming a search order, mearly uniq'ifying
201 627         838 my %seen;
202 627         1506 return grep { !$seen{$_}++ } map { $_, $_->superclasses } @superclasses;
  172         961  
  167         466  
203             }
204              
205             =head2 methods
206              
207             $methods = $class->methods
208              
209             Return all the methods available to this class as a HASH reference mapping
210             names to L instances.
211              
212             =cut
213              
214             method methods
215 16     16 1 45 {
216 16         27 my %methods;
217 16         45 foreach ( $self, $self->superclasses ) {
218 32         89 my $m = $_->direct_methods;
219 32   33     225 $methods{$_} ||= $m->{$_} for keys %$m;
220             }
221 16         101 return \%methods;
222             }
223              
224             =head2 method
225              
226             $method = $class->method( $name )
227              
228             Return the named method as a L instance, or C
229             if no such method exists.
230              
231             =cut
232              
233 8         12 method method ( $name )
  8         15  
  8         14  
234 8     8 1 21 {
235 8         31 return $self->methods->{$name};
236             }
237              
238             =head2 events
239              
240             $events = $class->events
241              
242             Return all the events available to this class as a HASH reference mapping
243             names to L instances.
244              
245             =cut
246              
247             method events
248 64     64 1 130 {
249 64         136 my %events;
250 64         177 foreach ( $self, $self->superclasses ) {
251 129         381 my $e = $_->direct_events;
252 129   33     876 $events{$_} ||= $e->{$_} for keys %$e;
253             }
254 64         430 return \%events;
255             }
256              
257             =head2 event
258              
259             $event = $class->event( $name )
260              
261             Return the named event as a L instance, or C if
262             no such event exists.
263              
264             =cut
265              
266 13         21 method event ( $name )
  13         24  
  13         17  
267 13     13 1 28 {
268 13         34 return $self->events->{$name};
269             }
270              
271             =head2 properties
272              
273             $properties = $class->properties
274              
275             Return all the properties available to this class as a HASH reference mapping
276             names to L instances.
277              
278             =cut
279              
280             method properties
281 379     379 1 694 {
282 379         580 my %properties;
283 379         906 foreach ( $self, $self->superclasses ) {
284 760         1637 my $p = $_->direct_properties;
285 760   33     7709 $properties{$_} ||= $p->{$_} for keys %$p;
286             }
287 379         2240 return \%properties;
288             }
289              
290             =head2 property
291              
292             $property = $class->property( $name )
293              
294             Return the named property as a L instance, or
295             C if no such property exists.
296              
297             =cut
298              
299 138         183 method property ( $name )
  138         255  
  138         188  
300 138     138 1 277 {
301 138         285 return $self->properties->{$name};
302             }
303              
304             =head1 AUTHOR
305              
306             Paul Evans
307              
308             =cut
309              
310             0x55AA;