File Coverage

blib/lib/Tangence/Meta/Class.pm
Criterion Covered Total %
statement 42 44 95.4
branch 1 2 50.0
condition 4 8 50.0
subroutine 9 10 90.0
pod 6 6 100.0
total 62 70 88.5


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