File Coverage

blib/lib/Defaults/Modern.pm
Criterion Covered Total %
statement 115 122 94.2
branch 10 16 62.5
condition 1 3 33.3
subroutine 25 25 100.0
pod n/a
total 151 166 90.9


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