1MooseX::Extended(3)   User Contributed Perl Documentation  MooseX::Extended(3)
2
3
4

NAME

6       MooseX::Extended - Extend Moose with safe defaults and useful features
7

VERSION

9       version 0.35
10

SYNOPSIS

12           package My::Names {
13               use MooseX::Extended types => [qw(compile Num NonEmptyStr Str PositiveInt ArrayRef)];
14               use List::Util 'sum';
15
16               # the distinction between `param` and `field` makes it easier to
17               # see which are available to `new`
18               param _name => ( isa => NonEmptyStr, init_arg => 'name' );
19               param title => ( isa => Str,         required => 0 );
20
21               # forbidden in the constructor
22               field created => ( isa => PositiveInt, default => sub {time} );
23
24               sub name ($self) {
25                   my $title = $self->title;
26                   my $name  = $self->_name;
27                   return $title ? "$title $name" : $name;
28               }
29
30               sub add ( $self, $args ) {
31                   state $check = compile( ArrayRef [ Num, 1 ] );    # at least one number
32                   ($args) = $check->($args);
33                   return sum( $args->@* );
34               }
35
36               sub warnit ($self) {
37                   carp("this is a warning");
38               }
39           }
40

DESCRIPTION

42       This module is BETA code. It's feature-complete for release and has no
43       known bugs. We believe it's ready for production, but make no promises.
44
45       This is a quick overview. See MooseX::Extended::Manual::Tutorial for
46       more information.
47
48       This class attempts to create a safer version of Moose that defaults to
49       read-only attributes and is easier to read and write.
50
51       It tries to bring some of the lessons learned from the Corinna project
52       <https://github.com/Ovid/Cor>, while acknowledging that you can't
53       always get what you want (such as true encapsulation and true methods).
54
55       This:
56
57           package My::Class {
58               use MooseX::Extended;
59
60               ... your code here
61           }
62
63       Is sort of the equivalent to:
64
65           package My::Class {
66               use v5.20.0;
67               use Moose;
68               use MooseX::StrictConstructor;
69               use feature qw( signatures postderef postderef_qq );
70               no warnings qw( experimental::signatures experimental::postderef );
71               use namespace::autoclean;
72               use Carp;
73               use mro 'c3';
74
75               ... your code here
76
77               __PACKAGE__->meta->make_immutable;
78           }
79           1;
80
81       It also exports two functions which are similar to Moose "has": "param"
82       and "field".
83
84       A "param" is a required parameter (defaults may be used). A "field" is
85       not intended to be passed to the constructor.
86
87       Note: the "has" function is still available, even if it's not needed.
88       Unlike "param" and "field", it still requires an "is" option.
89
90       Also, while your author likes the postfix block syntax, it's not
91       required. You can even safely inline multiple packages in the same
92       file:
93
94           package My::Point;
95           use MooseX::Extended types => 'Num';
96
97           param [ 'x', 'y' ] => ( isa => Num );
98
99           package My::Point::Mutable;
100           use MooseX::Extended;
101           extends 'My::Point';
102
103           param [ '+x', '+y' ] => ( writer => 1, clearer => 1, default => 0 );
104
105           sub invert ($self) {
106               my ( $x, $y ) = ( $self->x, $self->y );
107               $self->set_x($y);
108               $self->set_y($x);
109           }
110
111           # MooseX::Extended will cause this to return true, even if we try to return
112           # false
113           0;
114

CONFIGURATION

116       You may pass an import list to MooseX::Extended.
117
118           use MooseX::Extended
119             excludes => [qw/StrictConstructor carp/],      # I don't want these features
120             types    => [qw/compile PositiveInt HashRef/]; # I want these type tools
121
122   "types"
123       Allows you to import any types provided by MooseX::Extended::Types.
124
125       This:
126
127           use MooseX::Extended::Role types => [qw/compile PositiveInt HashRef/];
128
129       Is identical to this:
130
131           use MooseX::Extended::Role;
132           use MooseX::Extended::Types qw( compile PositiveInt HashRef );
133
134   "excludes"
135       You may find some features to be annoying, or even cause potential bugs
136       (e.g., if you have a "croak" method, our importing of "Carp::croak"
137       will be a problem.
138
139       A single argument to "excludes" can be a string. Multiple "excludes"
140       require an array reference:
141
142               use MooseX::Extended excludes => [qw/StrictConstructor autoclean/];
143
144       You can exclude the following:
145
146       •   "StrictConstructor"
147
148               use MooseX::Extended excludes => 'StrictConstructor';
149
150           Excluding this will no longer import "MooseX::StrictConstructor".
151
152       •   "autoclean"
153
154               use MooseX::Extended excludes => 'autoclean';
155
156           Excluding this will no longer import "namespace::autoclean".
157
158       •   "c3"
159
160               use MooseX::Extended excludes => 'c3';
161
162           Excluding this will no longer apply the C3 mro.
163
164       •   "carp"
165
166               use MooseX::Extended excludes => 'carp';
167
168           Excluding this will no longer import "Carp::croak" and
169           "Carp::carp".
170
171       •   "immutable"
172
173               use MooseX::Extended excludes => 'immutable';
174
175           Excluding this will no longer make your class immutable.
176
177       •   "true"
178
179               use MooseX::Extended excludes => 'true';
180
181           Excluding this will require your module to end in a true value.
182
183       •   "param"
184
185               use MooseX::Extended excludes => 'param';
186
187           Excluding this will make the "param" function unavailable.
188
189       •   "field"
190
191               use MooseX::Extended excludes => 'field';
192
193           Excluding this will make the "field" function unavailable.
194
195   "includes"
196       Several optional features of MooseX::Extended make this module much
197       more powerful. For example, to include try/catch and a "method"
198       keyword:
199
200               use MooseX::Extended includes => [ 'method', 'try' ];
201
202       A single argument to "includes" can be a string. Multiple "includes"
203       require an array reference:
204
205               use MooseX::Extended includes => [qw/method try/];
206
207       See MooseX::Extended::Manual::Includes for more information.
208

REDUCING BOILERPLATE

210       Let's say you've settled on the following feature set:
211
212           use MooseX::Extended
213             excludes => [qw/StrictConstructor carp/],
214             includes => 'method',
215             types    => ':Standard';
216
217       And you keep typing that over and over. We've removed a lot of
218       boilerplate, but we've added different boilerplate. Instead, just
219       create "My::Custom::Moose" and "use My::Custom::Moose;". See
220       MooseX::Extended::Custom for details.
221

IMMUTABILITY

223   Making Your Class Immutable
224       You no longer need to end your Moose classes with:
225
226           __PACKAGE__->meta->make_immutable;
227
228       That prevents further changes to the class and provides some
229       optimizations to make the code run much faster. However, it's somewhat
230       annoying to type. We do this for you, via B::Hooks::AtRuntime. You no
231       longer need to do this yourself.
232
233   Making Your Instance Immutable
234       By default, attributes defined via "param" and "field" are read-only.
235       However, if they contain a reference, you can fetch the reference,
236       mutate it, and now everyone with a copy of that reference has mutated
237       state.
238
239       To handle that, we offer a new "clone => $clone_type" pair for
240       attributes.
241
242       See the MooseX::Extended::Manual::Cloning documentation.
243

OBJECT CONSTRUCTION

245       Object construction for MooseX::Extended is identical to Moose because
246       MooseX::Extended is Moose, so no changes are needed.  However, in
247       addition to "has", we also provide "param" and "field" attributes, both
248       of which are "is => 'ro'" by default.
249
250       The "param" is required, whether by passing it to the constructor, or
251       using "default" or "builder".
252
253       The "field" is forbidden in the constructor and is lazy if it has a
254       builder, because that builder is often dependent on attributes set in
255       the constructor (and why call it if it's not used?).
256
257       Here's a short example:
258
259           package Class::Name {
260               use MooseX::Extended types => [qw(compile Num NonEmptyStr Str)];
261
262               # these default to 'ro' (but you can override that) and are required
263               param _name => ( isa => NonEmptyStr, init_arg => 'name' );
264               param title => ( isa => Str,         required => 0 );
265
266               # fields must never be passed to the constructor
267               # note that ->title and ->name are guaranteed to be set before
268               # this because fields are lazy by default
269               field name => (
270                   isa     => NonEmptyStr,
271                   default => sub ($self) {
272                       my $title = $self->title;
273                       my $name  = $self->_name;
274                       return $title ? "$title $name" : $name;
275                   },
276               );
277           }
278
279       See MooseX::Extended::Manual::Construction for a full explanation.
280

ATTRIBUTE SHORTCUTS

282       When using "field" or "param", we have some attribute shortcuts:
283
284           param name => (
285               isa       => NonEmptyStr,
286               writer    => 1,   # set_name
287               reader    => 1,   # get_name
288               predicate => 1,   # has_name
289               clearer   => 1,   # clear_name
290               builder   => 1,   # _build_name
291           );
292
293           sub _build_name ($self) {
294               ...
295           }
296
297       You can also do this:
298
299           param name ( isa => NonEmptyStr, builder => sub {...} );
300
301       That's the same as:
302
303           param name ( isa => NonEmptyStr, builder => '_build_name' );
304
305           sub _build_name {...}
306
307       See MooseX::Extended::Manual::Shortcuts for a full explanation.
308

INVALID ATTRIBUTE DEFINITIONS

310       The following Moose code will print "WhoAmI". However, the second
311       attribute name is clearly invalid.
312
313           package Some::Class {
314               use Moose;
315
316               has name   => ( is => 'ro' );
317               has '-bad' => ( is => 'ro' );
318           }
319
320           my $object = Some::Class->new( name => 'WhoAmI' );
321           say $object->name;
322
323       "MooseX::Extended" will throw a
324       Moose::Exception::InvalidAttributeDefinition exception if it encounters
325       an illegal method name for an attribute.
326
327       This also applies to various attributes which allow method names, such
328       as "clone", "builder", "clearer", "writer", "reader", and "predicate".
329
330       Trying to pass a defined "init_arg" to "field" will also throw this
331       exception, unless the init_arg begins with an underscore. (It is
332       sometimes useful to be able to define an "init_arg" for unit testing.)
333

BUGS AND LIMITATIONS

335       None known at this time.
336

MANUAL

338       •   MooseX::Extended::Manual::Tutorial
339
340       •   MooseX::Extended::Manual::Overview
341
342       •   MooseX::Extended::Manual::Construction
343
344       •   MooseX::Extended::Manual::Includes
345
346       •   MooseX::Extended::Manual::Shortcuts
347
348       •   MooseX::Extended::Manual::Cloning
349
351       •   MooseX::Extended::Types is included in the distribution.
352
353           This provides core types for you.
354
355       •   MooseX::Extended::Role is included in the distribution.
356
357           "MooseX::Extended", but for roles.
358

TODO

360       Some of this may just be wishful thinking. Some of this would be
361       interesting if others would like to collaborate.
362
363   Configurable Types
364       We provide "MooseX::Extended::Types" for convenience, along with the
365       "declare" function. We should write up (and test) examples of extending
366       it.
367
368   "BEGIN::Lift"
369       This idea maybe belongs in "MooseX::Extended::OverKill", but ...
370
371       Quite often you see things like this:
372
373           BEGIN { extends 'Some::Parent' }
374
375       Or this:
376
377           sub serial_number; # required by a role, must be compile-time
378           has serial_number => ( ... );
379
380       In fact, there are a variety of Moose functions which would work better
381       if they ran at compile-time instead of runtime, making them look a
382       touch more like native functions. My various attempts at solving this
383       have failed, but I confess I didn't try too hard.
384

NOTES

386       There are a few things you might be interested to know about this
387       module when evaluating it.
388
389       Most of this is written with bog-standard Moose, so there's nothing
390       terribly weird inside, but you may wish to note that we use
391       B::Hooks::AtRuntime and true. They seem sane, but caveat emptor.
392

SEE ALSO

394       •   Corinna <https://github.com/Ovid/Cor>
395
396           The RFC of the new version of OOP planned for the Perl core.
397
398       •   MooseX::Modern <https://metacpan.org/pod/MooseX::Modern>
399
400           MooseX::Modern - Precision classes for Modern Perl
401
402       •   Zydeco <https://metacpan.org/pod/Zydeco>
403
404           Zydeco - Jazz up your Perl
405
406       •   Dios <https://metacpan.org/pod/Dios>
407
408           Dios - Declarative Inside-Out Syntax
409
410       •   MooseX::AttributeShortcuts
411           <https://metacpan.org/pod/MooseX::AttributeShortcuts>
412
413           MooseX::AttributeShortcuts - Shorthand for common attribute options
414

AUTHOR

416       Curtis "Ovid" Poe <curtis.poe@gmail.com>
417
419       This software is Copyright (c) 2022 by Curtis "Ovid" Poe.
420
421       This is free software, licensed under:
422
423         The Artistic License 2.0 (GPL Compatible)
424
425
426
427perl v5.38.0                      2023-06-26               MooseX::Extended(3)
Impressum