File Coverage

blib/lib/Defaults/Modern.pm
Criterion Covered Total %
statement 119 126 94.4
branch 10 16 62.5
condition 1 3 33.3
subroutine 26 26 100.0
pod n/a
total 156 171 91.2


line stmt bran cond sub pod time code
1             package Defaults::Modern;
2             $Defaults::Modern::VERSION = '0.011001';
3 1     1   13834 use v5.14;
  1         3  
4              
5 1     1   412 use strictures 2;
  1         1167  
  1         30  
6 1     1   587 no indirect ':fatal';
  1         850  
  1         3  
7 1     1   463 no bareword::filehandles;
  1         2762  
  1         5  
8              
9 1     1   460 use Module::Runtime 'use_package_optimistically';
  1         1437  
  1         6  
10 1     1   517 use Try::Tiny;
  1         1599  
  1         47  
11 1     1   407 use Import::Into;
  1         328  
  1         26  
12              
13              
14 1     1   6 use Carp ();
  1         1  
  1         14  
15 1     1   4 use feature ();
  1         1  
  1         12  
16 1     1   373 use true ();
  1         6166  
  1         744  
17              
18 1     1   397 use match::simple ();
  1         4437  
  1         20  
19              
20 1     1   353 use Defaults::Modern::Define ();
  1         3  
  1         24  
21 1     1   448 use Function::Parameters ();
  1         1826  
  1         21  
22 1     1   410 use List::Objects::WithUtils ();
  1         672  
  1         20  
23 1     1   659 use Path::Tiny ();
  1         8255  
  1         27  
24 1     1   432 use PerlX::Maybe ();
  1         1393  
  1         19  
25 1     1   363 use Quote::Code ();
  1         551  
  1         19  
26 1     1   4 use Scalar::Util ();
  1         1  
  1         12  
27 1     1   364 use Switch::Plain ();
  1         557  
  1         19  
28              
29 1     1   453 use Types::Standard ();
  1         48601  
  1         36  
30 1     1   476 use Types::Path::Tiny ();
  1         17522  
  1         33  
31 1     1   423 use Type::Registry ();
  1         20028  
  1         32  
32 1     1   7 use Type::Utils ();
  1         2  
  1         16  
33 1     1   641 use List::Objects::Types ();
  1         71964  
  1         832  
34              
35              
36             sub import {
37 7     7   14082 my $class = shift;
38 7         16 my $pkg = caller;
39              
40             state $known = +{
41 7         14 map {; $_ => 1 } qw/
  3         26  
42             all
43             autobox_lists
44             moo
45             /
46             };
47              
48 7         12 my %params;
49 7         10 my $idx = 0;
50 7         9 my $typelibs;
51 7         18 PARAM: for my $item (@_) {
52 5         16 my $current = $idx++;
53 5 50 33     38 if ($item eq 'with_types' || $item eq '-with_types') {
54             # backwards-compat ; may go away someday
55 0         0 Carp::carp(
56             "'with_types' option is deprecated; ",
57             "'use TYPELIB -all' after 'use Defaults::Modern;' instead"
58             );
59 0         0 $typelibs = $_[$idx];
60 0         0 splice @_, $current, 2;
61 0 0       0 if (ref $typelibs) {
62 0 0       0 Carp::croak "with_types should be an ARRAY, got $typelibs"
63             if Scalar::Util::reftype($typelibs) ne 'ARRAY';
64             } else {
65 0         0 $typelibs = [ $typelibs ]
66             }
67             next PARAM
68 0         0 }
69              
70 5         22 my $opt = lc($item =~ s/^(?:[-:])//r);
71 5 100       259 Carp::croak("$class does not export $opt") unless $known->{$opt};
72              
73 4 100       10 if ($opt eq 'all') {
74 2         7 $params{$_} = 1 for grep {; $_ ne 'all' } keys %$known;
  6         14  
75             next PARAM
76 2         6 }
77              
78 2         6 $params{$opt} = 1;
79             }
80              
81             # Us
82 6         78 Defaults::Modern::Define->import::into($pkg);
83              
84             # Core
85 6         280 Carp->import::into($pkg,
86             qw/carp croak confess/,
87             );
88              
89 6         1144 Scalar::Util->import::into($pkg,
90             qw/blessed reftype weaken/,
91             );
92            
93             # Pragmas
94 6         1051 strictures->import::into($pkg, version => 2);
95 6         1956 bareword::filehandles->unimport;
96 6         71 indirect->unimport(':fatal');
97 6         185 warnings->unimport('once');
98 6 50       24 if ($] >= 5.018) {
99 6         36 warnings->unimport('experimental');
100             }
101              
102 6         350 feature->import(':5.14');
103 6         77 feature->unimport('switch');
104              
105 6         35 match::simple->import::into($pkg);
106 6         3233 true->import;
107              
108             # External functionality
109              
110             state $fp_defaults = +{
111             strict => 1,
112             default_arguments => 1,
113             named_parameters => 1,
114             types => 1,
115             reify_type => sub {
116 4     4   9396 state $guard = do { require Type::Utils };
  1         7  
117 4         22 Type::Utils::dwim_type($_[0], for => $_[1])
118             },
119 6         2840 };
120              
121 6         123 Function::Parameters->import(
122             +{
123             fun => {
124             name => 'optional',
125             %$fp_defaults
126             },
127             method => {
128             name => 'required',
129             attributes => ':method',
130             shift => '$self',
131             invocant => 1,
132             %$fp_defaults
133             }
134             }
135             );
136              
137 6         1854 Path::Tiny->import::into($pkg, 'path');
138              
139 6         1079 PerlX::Maybe->import::into($pkg, qw/maybe provided/);
140              
141 6         1009 Quote::Code->import::into($pkg, qw/qc qcw qc_to/);
142              
143 6         1082 Try::Tiny->import::into($pkg);
144 6         1031 Switch::Plain->import;
145              
146             $params{autobox_lists} ?
147 6 100       173 List::Objects::WithUtils->import::into($pkg, 'all')
148             : List::Objects::WithUtils->import::into($pkg);
149              
150             # Types
151 6         18074 state $mytypelibs = [ qw/
152             Types::Standard
153             Types::Path::Tiny
154             List::Objects::Types
155             / ];
156              
157 6         16 for my $typelib (@$mytypelibs, @$typelibs) {
158 18         169473 use_package_optimistically($typelib)->import::into($pkg, -all);
159             # Irrelevant with Type::Tiny-1.x ->
160             # try {
161             # Type::Registry->for_class($pkg)->add_types($typelib);
162             # } catch {
163             # Usually conflicts; whine but prefer user's previous imports:
164             # Carp::carp($_)
165             # };
166             }
167              
168 6 100       22442 if (defined $params{moo}) {
169 3         728 require Moo;
170 3         5849 Moo->import::into($pkg);
171             }
172              
173             $class
174 6         4175 }
175              
176             1;
177              
178             =pod
179              
180             =head1 NAME
181              
182             Defaults::Modern - Yet another approach to modernistic Perl
183              
184             =head1 SYNOPSIS
185              
186             use Defaults::Modern;
187              
188             # Function::Parameters + List::Objects::WithUtils + types ->
189             fun to_immutable ( (ArrayRef | ArrayObj) $arr ) {
190             # blessed() and confess() are available (amongst others):
191             my $immutable = immarray( blessed $arr ? $arr->all : @$arr );
192             confess 'No items in array!' unless $immutable->has_any;
193             $immutable
194             }
195              
196             package My::Foo {
197             use Defaults::Modern;
198              
199             # define keyword for defining constants ->
200             define ARRAY_MAX = 10;
201              
202             # Moo(se) with types ->
203             use Moo;
204              
205             has myarray => (
206             is => 'ro',
207             isa => ArrayObj,
208             writer => '_set_myarray',
209             coerce => 1,
210             builder => sub { [] },
211             );
212              
213             # Method with optional positional param and implicit $self ->
214             method slice_to_max (Int $max = -1) {
215             my $arr = $self->myarray;
216             $self->_set_myarray(
217             $arr->sliced( 0 .. $max >= 0 ? $max : ARRAY_MAX )
218             )
219             }
220             }
221              
222             # Optionally autobox list-type refs via List::Objects::WithUtils ->
223             use Defaults::Modern 'autobox_lists';
224             my $obj = +{ foo => 'bar', baz => 'quux' }->inflate;
225             my $baz = $obj->baz;
226              
227             # See DESCRIPTION for complete details on imported functionality.
228              
229             =head1 DESCRIPTION
230              
231             Yet another approach to writing Perl in a modern style.
232              
233             . . . also saves me extensive typing ;-)
234              
235             When you C, you get:
236              
237             =over
238              
239             =item *
240              
241             L (version 2), which enables L and makes most warnings
242             fatal; additionally L and L method calls are
243             disallowed explicitly (not just in development environments)
244              
245             =item *
246              
247             The C feature set (C, C, C, C) -- except for
248             C, which is deprecated in newer perls (and L is
249             provided anyway).
250              
251             C warnings are also disabled on C.
252              
253             =item *
254              
255             B, B, and B error reporting tools from L
256              
257             =item *
258              
259             B, B, and B utilities from L
260              
261             =item *
262              
263             All of the L object constructors (B,
264             B, B, B, B, B, B,
265             B)
266              
267             =item *
268              
269             B and B keywords from L configured to
270             accept L types (amongst other reasonably sane defaults including
271             arity checks)
272              
273             =item *
274              
275             The full L set and L -- useful in
276             combination with L (see the L and
277             L POD)
278              
279             =item *
280              
281             B and B from L
282              
283             =item *
284              
285             The B object constructor from L and related types/coercions
286             from L
287              
288             =item *
289              
290             B and B definedness-checking syntax sugar from L
291              
292             =item *
293              
294             A B keyword for defining constants based on L
295              
296             =item *
297              
298             The B<|M|> match operator from L
299              
300             =item *
301              
302             The B and B switch/case constructs from L
303              
304             =item *
305              
306             The B, B, and B code-interpolating keywords from
307             L (as of Defaults::Modern C)
308              
309             =item *
310              
311             L.pm so you can skip adding '1;' to all of your modules
312              
313             =back
314              
315             If you import the tag C, ARRAY and HASH type references are autoboxed
316             via L:
317              
318             use Defaults::Modern 'autobox_lists';
319             my $itr = [ 1 .. 10 ]->natatime(2);
320              
321             L version 2+ is depended upon in order to guarantee availability, but not
322             automatically imported:
323              
324             use Defaults::Modern;
325             use Moo;
326             use MooX::TypeTiny; # recommended for faster inline type checks
327              
328             has foo => (
329             is => 'ro',
330             isa => ArrayObj,
331             coerce => 1,
332             default => sub { [] },
333             );
334              
335             If you're building classes, you may want to look into L /
336             L or similar -- L imports an awful lot of
337             Stuff:
338              
339             use Defaults::Modern;
340             use Moo;
341             use namespace::clean;
342             # ...
343              
344             =head1 SEE ALSO
345              
346             This package just glues together useful parts of CPAN, the
347             most visible portions of which come from the following modules:
348              
349             L
350              
351             L
352              
353             L and L
354              
355             L
356              
357             L
358              
359             L
360              
361             L
362              
363             L
364              
365             L
366              
367             L
368              
369             L
370              
371             L
372              
373             =head1 AUTHOR
374              
375             Jon Portnoy
376              
377             Licensed under the same terms as Perl.
378              
379             Inspired by L and L.
380              
381             The code backing the B keyword is forked from TOBYINK's
382             L to avoid the L dependency and is copyright Toby
383             Inkster.
384              
385             =cut
386              
387             # vim: ts=2 sw=2 et sts=2 ft=perl