File Coverage

blib/lib/Feature/Compat/Class.pm
Criterion Covered Total %
statement 15 15 100.0
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 20 20 100.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, 2022-2023 -- leonerd@leonerd.org.uk
5              
6             package Feature::Compat::Class 0.06;
7              
8 12     12   1174442 use v5.14;
  12         182  
9 12     12   68 use warnings;
  12         28  
  12         342  
10 12     12   88 use feature ();
  12         25  
  12         560  
11              
12 12     12   78 use constant HAVE_FEATURE_CLASS => defined $feature::feature{class};
  12         23  
  12         3110  
13              
14             =head1 NAME
15              
16             C - make C syntax available
17              
18             =head1 SYNOPSIS
19              
20             use Feature::Compat::Class;
21              
22             class Point {
23             field $x :param = 0;
24             field $y :param = 0;
25              
26             method move_to ($new_x, $new_y) {
27             $x = $new_x;
28             $y = $new_y;
29             }
30              
31             method describe {
32             say "A point at ($x, $y)";
33             }
34             }
35              
36             Point->new(x => 5, y => 10)->describe;
37              
38             =head1 DESCRIPTION
39              
40             This module provides the new C keyword and related others (C,
41             C and C) in a forward-compatible way.
42              
43             Perl added such syntax at version 5.38.0, which is enabled by
44              
45             use feature 'class';
46              
47             On that version of perl or later, this module simply enables the core feature
48             equivalent of using it directly. On such perls, this module will install with
49             no non-core dependencies, and requires no C compiler.
50              
51             On older versions of perl before such syntax is availble in core, it is
52             currently provided instead using the L module, imported with a
53             special set of options to configure it to only recognise the same syntax as
54             the core perl feature, thus ensuring any code using it will still continue to
55             function on that newer perl.
56              
57             This module is a work-in-progress, because the underlying C
58             is too. Many of the limitations and inabilities listed below are a result of
59             the early-access nature of this branch, and are expected to be lifted as work
60             progresses towards a more featureful and complete implementation.
61              
62             =cut
63              
64             sub import
65             {
66 12     12   83 if( HAVE_FEATURE_CLASS ) {
67             feature->import(qw( class ));
68             require warnings;
69             warnings->unimport(qw( experimental::class ));
70             }
71             else {
72 12         7395 require Object::Pad;
73 12         135615 Object::Pad->VERSION( '0.78' );
74 12         68 Object::Pad->import(qw( class method field ADJUST ),
75             ':experimental(init_expr)',
76             ':config(' .
77             'always_strict only_class_attrs=isa only_field_attrs=param ' .
78             'no_field_block no_adjust_attrs no_implicit_pragmata' .
79             ')',
80             );
81             }
82             }
83              
84             =head1 KEYWORDS
85              
86             The keywords provided by this module offer a subset of the abilities of those
87             provided by C, restricted to specifically only what is commonly
88             supported by the core syntax as well. In general, the reader should first
89             consult the documentation for the corresponding C keyword, but
90             the following notes may be of interest:
91              
92             =head2 class
93              
94             class NAME { ... }
95             class NAME VERSION { ... }
96              
97             class NAME; ...
98             class NAME VERSION; ...
99              
100             See also L.
101              
102             There is no ability to declare any roles with C<:does>. The legacy subkeywords
103             for these are equally not supported.
104              
105             The C<:repr> attribute is also not supported; the default representation type
106             will always be selected.
107              
108             The C<:strict(params)> attribute is not available, but all constructed classes
109             will behave as if the attribute had been declared. Every generated constructor
110             will check its parameters for key names left unhandled by C blocks,
111             and throw an exception if any remain.
112              
113             The following class attributes are supported:
114              
115             =head3 :isa
116              
117             :isa(CLASS)
118              
119             :isa(CLASS CLASSVER)
120              
121             I
122              
123             Declares a superclass that this class extends. At most one superclass is
124             supported.
125              
126             If the package providing the superclass does not exist, an attempt is made to
127             load it by code equivalent to
128              
129             require CLASS ();
130              
131             and thus it must either already exist, or be locatable via the usual C<@INC>
132             mechanisms.
133              
134             An optional version check can also be supplied; it performs the equivalent of
135              
136             BaseClass->VERSION( $ver )
137              
138             Note that C blocks B implicitly enable the C and
139             C pragmata; either when using the core feature or C.
140             This is to avoid surprises when eventually switching to purely using the core
141             perl feature, which will not do that. Remember however that a C
142             of a version C or above will enable both these pragmata anyway, so that
143             will be sufficient.
144              
145             =head2 method
146              
147             method NAME { ... }
148             method NAME;
149              
150             See also L.
151              
152             Attributes are not supported, other than the usual ones provided by perl
153             itself. Of these, only C<:lvalue> is particularly useful.
154              
155             Lexical methods are not supported.
156              
157             =head2 field
158              
159             field $NAME;
160             field @NAME;
161             field %NAME;
162              
163             field $NAME = EXPR;
164              
165             field $NAME :ATTRS... = EXPR;
166              
167             See also L.
168              
169             Most field attributes are not supported. In particular, rather than using the
170             accessor-generator attributes you will have to create accessor methods
171             yourself; such as
172              
173             field $var;
174             method var { return $var; }
175             method set_var ($new_var) { $var = $new_var; }
176              
177             I fields of any type may take initialising expressions.
178             Initialiser blocks are not supported.
179              
180             field $five = 5;
181              
182             The following field attributes are supported:
183              
184             =head3 :param
185              
186             field $var :param;
187              
188             field $var :param(name)
189              
190             I
191              
192             Declares that the constructor will take a named parameter to set the value for
193             this field in a new instance.
194              
195             field $var :param = EXPR;
196              
197             Without a defaulting expression, the parameter is mandatory. When combined
198             with a defaulting expression, the parameter is optional and the default will
199             only apply if the named parameter was not passed to the constructor.
200              
201             field $var :param //= EXPR;
202             field $var :param ||= EXPR;
203              
204             With both the C<:param> attribute and a defaulting expression, the operator
205             can also be written as C or C<||=>. In this case, the defaulting
206             expression will be used even if the caller passed an undefined value (for
207             C) or a false value (for C<||=>). This simplifies many situations where
208             C would not be a valid value for a field parameter.
209              
210             class C {
211             field $timeout :param //= 20;
212             }
213              
214             C->new( timeout => $args{timeout} );
215             # default applies if %args has no 'timeout' key, or if its value is undef
216              
217             =head2 ADJUST
218              
219             ADJUST { ... }
220              
221             See also L.
222              
223             Attributes are not supported; in particular the C<:params> attribute of
224             C v0.70.
225              
226             =head2 Other Keywords
227              
228             The following other keywords provided by C are not supported here
229             at all:
230              
231             role
232              
233             BUILD, ADJUSTPARAMS
234              
235             has
236              
237             requires
238              
239             =cut
240              
241             =head1 COMPATIBILITY NOTES
242              
243             This module may use either L or the perl core C feature to
244             implement its syntax. While the two behave very similarly and both conform to
245             the description given above, the following differences should be noted.
246              
247             =over 4
248              
249             =item Fields in later field expressions
250              
251             The core perl C feature makes every field variable visible to the
252             initialising expression of later fields. For example,
253              
254             field $one = 1;
255             field $two = $one + 1;
256              
257             This is not currently supported by C. As a result, it is possible
258             to write code that works fine with the core perl feature but older perls
259             cannot support by using C.
260              
261             =back
262              
263             =cut
264              
265             =head1 AUTHOR
266              
267             Paul Evans
268              
269             =cut
270              
271             0x55AA;