File Coverage

blib/lib/Reindeer.pm
Criterion Covered Total %
statement 38 38 100.0
branch 4 22 18.1
condition n/a
subroutine 9 9 100.0
pod 0 1 0.0
total 51 70 72.8


line stmt bran cond sub pod time code
1             #
2             # This file is part of Reindeer
3             #
4             # This software is Copyright (c) 2017, 2015, 2014, 2012, 2011 by Chris Weyl.
5             #
6             # This is free software, licensed under:
7             #
8             # The GNU Lesser General Public License, Version 2.1, February 1999
9             #
10             package Reindeer;
11             our $AUTHORITY = 'cpan:RSRCHBOY';
12             # git description: 0.018-20-g9af504b
13             $Reindeer::VERSION = '0.019';
14              
15             # ABSTRACT: Moose with more antlers
16              
17 11     11   1379659 use strict;
  11         687  
  11         272  
18 11     11   60 use warnings;
  11         21  
  11         249  
19              
20 11     11   3060 use Reindeer::Util;
  11         34  
  11         86  
21 11     11   2254 use Moose::Exporter 2.1400;
  11         175  
  11         71  
22 11     11   4236 use Import::Into;
  11         4031  
  11         376  
23 11     11   62 use Class::Load;
  11         23  
  11         403  
24              
25 11     11   4140 use MooseX::Traitor 0.002;
  11         542841  
  11         387  
26 11     11   90 use Moose::Util::TypeConstraints ();
  11         23  
  11         2333  
27              
28             my (undef, undef, $init_meta) = Moose::Exporter->build_import_methods(
29             install => [ qw{ import unimport } ],
30              
31             also => [ 'Moose', Reindeer::Util::also_list() ],
32             trait_aliases => [ Reindeer::Util::trait_aliases() ],
33             as_is => [ Reindeer::Util::as_is() ],
34              
35             base_class_roles => [ qw{ MooseX::Traitor } ],
36             );
37              
38             sub init_meta {
39 65     65 0 4231244 my ($class, %options) = @_;
40 65         193 my $for_class = $options{for_class};
41              
42             # enable features to the level of Perl being used
43 65 0       358 my $features
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
44             = $] >= 5.026 ? ':5.26'
45             : $] >= 5.024 ? ':5.24'
46             : $] >= 5.022 ? ':5.22'
47             : $] >= 5.020 ? ':5.20'
48             : $] >= 5.018 ? ':5.18'
49             : $] >= 5.016 ? ':5.16'
50             : $] >= 5.014 ? ':5.14'
51             : $] >= 5.012 ? ':5.12'
52             : $] >= 5.010 ? ':5.10'
53             : undef
54             ;
55              
56 65 50       227 do { require feature; feature->import($features) }
  65         441  
  65         5151  
57             if $features;
58              
59             ### $for_class
60 65         364 Moose->init_meta(for_class => $for_class);
61              
62             ### more properly in import()?
63 65         262599 Reindeer::Util->import_type_libraries({ -into => $for_class });
64 65         4581 Path::Class->export_to_level(1);
65 65         546 Try::Tiny->import::into(1);
66 65         14009 MooseX::Params::Validate->import({ into => $for_class });
67 65         25878 Moose::Util::TypeConstraints->import(
68             { into => $for_class },
69             qw{ class_type role_type duck_type },
70             );
71 65         38820 MooseX::MarkAsMethods->import({ into => $for_class }, autoclean => 1);
72              
73 65 50       404668 goto $init_meta if $init_meta;
74             }
75              
76             !!42;
77              
78             __END__
79              
80             =pod
81              
82             =encoding UTF-8
83              
84             =for :stopwords Chris Weyl Alex Balhatchet AutoDestruct MultiInitArg UndefTolerant
85             autoclean rwp ttl metaclass Specifing
86              
87             =head1 NAME
88              
89             Reindeer - Moose with more antlers
90              
91             =head1 VERSION
92              
93             This document describes version 0.019 of Reindeer - released June 09, 2017 as part of Reindeer.
94              
95             =head1 SYNOPSIS
96              
97             # ta-da!
98             use Reindeer;
99              
100             # ...is the same as:
101             use feature ':5.xx'; # where xx is appropriate for your running perl
102             use Moose;
103             use MooseX::MarkAsMethods autoclean => 1;
104             use MooseX::AlwaysCoerce;
105             use MooseX::AttributeShortcuts;
106             # etc, etc, etc
107              
108             =head1 DESCRIPTION
109              
110             Like L<Moose>? Use MooseX::* extensions? Maybe some L<MooseX::Types>
111             libraries? Hate that you have to use them in every. Single. Class.
112              
113             Reindeer aims to resolve that :) Reindeer _is_ Moose -- it's just Moose with
114             a number of the more useful/popular extensions already applied. Reindeer is a
115             drop-in replacement for your "use Moose" line, that behaves in the exact same
116             way... Just with more pointy antlers.
117              
118             =for Pod::Coverage init_meta
119              
120             =head1 EARLY RELEASE!
121              
122             Be aware this package should be considered early release code. While L<Moose>
123             and all our incorporated extensions have their own classifications (generally
124             GA or "stable"), this bundling is still under active development, and more
125             extensions, features and the like may still be added.
126              
127             That said, my goal here is to increase functionality, not decrease it.
128              
129             When this package hits GA / stable, I'll set the release to be >= 1.000.
130              
131             =head1 NEW CLASS METHODS
132              
133             =head2 with_traits()
134              
135             This method allows you to easily compose a new class with additional traits:
136              
137             my $foo = Bar->with_traits('Stools', 'Norm')->new(beer => 1, tab => undef);
138              
139             (See also L<MooseX::Traits>.)
140              
141             =head1 NEW ATTRIBUTE OPTIONS
142              
143             Unless specified here, all options defined by Moose::Meta::Attribute
144             and Class::MOP::Attribute remain unchanged.
145              
146             For the following, "$name" should be read as the attribute name; and the
147             various prefixes should be read using the defaults
148              
149             =head2 coerce => 0
150              
151             Coercion is ENABLED by default; explicitly pass "coerce => 0" to disable.
152              
153             (See also L<MooseX::AlwaysCoerce>.)
154              
155             =head2 lazy_require => 1
156              
157             The reader methods for all attributes with that option will throw an exception
158             unless a value for the attributes was provided earlier by a constructor
159             parameter or through a writer method.
160              
161             (See also L<MooseX::LazyRequire>.)
162              
163             =head2 is => 'rwp'
164              
165             Specifying C<is =E<gt> 'rwp'> will cause the following options to be set:
166              
167             is => 'ro'
168             writer => "_set_$name"
169              
170             rwp can be read as "read + write private".
171              
172             =head2 is => 'lazy'
173              
174             Specifying C<is =E<gt> 'lazy'> will cause the following options to be set:
175              
176             is => 'ro'
177             builder => "_build_$name"
178             lazy => 1
179              
180             B<NOTE:> Since 0.009 we no longer set C<init_arg =E<gt> undef> if no C<init_arg>
181             is explicitly provided. This is a change made in parallel with L<Moo>, based
182             on a large number of people surprised that lazy also made one's C<init_def>
183             undefined.
184              
185             =head2 is => 'lazy', default => ...
186              
187             Specifying C<is =E<gt> 'lazy'> and a default will cause the following options to be
188             set:
189              
190             is => 'ro'
191             lazy => 1
192             default => ... # as provided
193              
194             That is, if you specify C<is =E<gt> 'lazy'> and also provide a C<default>, then
195             we won't try to set a builder, as well.
196              
197             =head2 builder => 1
198              
199             Specifying C<builder =E<gt> 1> will cause the following options to be set:
200              
201             builder => "_build_$name"
202              
203             =head2 builder => sub { ... }
204              
205             Passing a coderef to builder will cause that coderef to be installed in the
206             class this attribute is associated with the name you'd expect, and
207             C<builder =E<gt> 1> to be set.
208              
209             e.g., in your class (or role),
210              
211             has foo => (is => 'ro', builder => sub { 'bar!' });
212              
213             ...is effectively the same as...
214              
215             has foo => (is => 'ro', builder => '_build_foo');
216             sub _build_foo { 'bar!' }
217              
218             The behaviour of this option in roles changed in 0.030, and the builder
219             methods will be installed in the role itself. This means you can
220             alias/exclude/etc builder methods in roles, just as you can with any other
221             method.
222              
223             =head2 clearer => 1
224              
225             Specifying C<clearer =E<gt> 1> will cause the following options to be set:
226              
227             clearer => "clear_$name"
228              
229             or, if your attribute name begins with an underscore:
230              
231             clearer => "_clear$name"
232              
233             (that is, an attribute named "_foo" would get "_clear_foo")
234              
235             =head2 predicate => 1
236              
237             Specifying C<predicate =E<gt> 1> will cause the following options to be set:
238              
239             predicate => "has_$name"
240              
241             or, if your attribute name begins with an underscore:
242              
243             predicate => "_has$name"
244              
245             (that is, an attribute named "_foo" would get "_has_foo")
246              
247             =head2 trigger => 1
248              
249             Specifying C<trigger =E<gt> 1> will cause the attribute to be created with a trigger
250             that calls a named method in the class with the options passed to the trigger.
251             By default, the method name the trigger calls is the name of the attribute
252             prefixed with "_trigger_".
253              
254             e.g., for an attribute named "foo" this would be equivalent to:
255              
256             trigger => sub { shift->_trigger_foo(@_) }
257              
258             For an attribute named "_foo":
259              
260             trigger => sub { shift->_trigger__foo(@_) }
261              
262             This naming scheme, in which the trigger is always private, is the same as the
263             builder naming scheme (just with a different prefix).
264              
265             =head2 handles => { foo => sub { ... }, ... }
266              
267             Creating a delegation with a coderef will now create a new, "custom accessor"
268             for the attribute. These coderefs will be installed and called as methods on
269             the associated class (just as readers, writers, and other accessors are), and
270             will have the attribute metaclass available in $_. Anything the accessor
271             is called with it will have access to in @_, just as you'd expect of a method.
272              
273             e.g., the following example creates an attribute named 'bar' with a standard
274             reader accessor named 'bar' and two custom accessors named 'foo' and
275             'foo_too'.
276              
277             has bar => (
278              
279             is => 'ro',
280             isa => 'Int',
281             handles => {
282              
283             foo => sub {
284             my $self = shift @_;
285              
286             return $_->get_value($self) + 1;
287             },
288              
289             foo_too => sub {
290             my $self = shift @_;
291              
292             return $self->bar + 1;
293             },
294              
295             # ...as you'd expect.
296             bar => 'bar',
297             },
298             );
299              
300             ...and later,
301              
302             Note that in this example both foo() and foo_too() do effectively the same
303             thing: return the attribute's current value plus 1. However, foo() accesses
304             the attribute value directly through the metaclass, the pros and cons of
305             which this author leaves as an exercise for the reader to determine.
306              
307             You may choose to use the installed accessors to get at the attribute's value,
308             or use the direct metaclass access, your choice.
309              
310             =head1 NEW KEYWORDS (SUGAR)
311              
312             In addition to all sugar provided by L<Moose> (e.g. has, with, extends), we
313             provide a couple new keywords.
314              
315             =head2 B<class_type ($class, ?$options)>
316              
317             Creates a new subtype of C<Object> with the name C<$class> and the
318             metaclass L<Moose::Meta::TypeConstraint::Class>.
319              
320             # Create a type called 'Box' which tests for objects which ->isa('Box')
321             class_type 'Box';
322              
323             By default, the name of the type and the name of the class are the same, but
324             you can specify both separately.
325              
326             # Create a type called 'Box' which tests for objects which ->isa('ObjectLibrary::Box');
327             class_type 'Box', { class => 'ObjectLibrary::Box' };
328              
329             (See also L<Moose::Util::TypeConstraints>.)
330              
331             =head2 B<role_type ($role, ?$options)>
332              
333             Creates a C<Role> type constraint with the name C<$role> and the
334             metaclass L<Moose::Meta::TypeConstraint::Role>.
335              
336             # Create a type called 'Walks' which tests for objects which ->does('Walks')
337             role_type 'Walks';
338              
339             By default, the name of the type and the name of the role are the same, but
340             you can specify both separately.
341              
342             # Create a type called 'Walks' which tests for objects which ->does('MooseX::Role::Walks');
343             role_type 'Walks', { role => 'MooseX::Role::Walks' };
344              
345             (See also L<Moose::Util::TypeConstraints>.)
346              
347             =head2 class_has => (...)
348              
349             Exactly like L<Moose/has>, but operates at the class (rather than instance)
350             level.
351              
352             (See also L<MooseX::ClassAttribute>.)
353              
354             =head2 default_for
355              
356             default_for() is a shortcut to extend an attribute to give it a new default;
357             this default value may be any legal value for default options.
358              
359             # attribute bar defined elsewhere (e.g. superclass)
360             default_for bar => 'new default';
361              
362             ... is the same as:
363              
364             has '+bar' => (default => 'new default');
365              
366             =head2 abstract
367              
368             abstract() allows one to declare a method dependency that must be satisfied by a
369             subclass before it is invoked, and before the subclass is made immutable.
370              
371             abstract 'method_name_that_must_be_satisfied';
372              
373             =head2 requires
374              
375             requires() is a synonym for abstract() and works in the way you'd expect.
376              
377             =head1 OVERLOADS
378              
379             It is safe to use overloads in your Reindeer classes and roles; they will
380             work just as you expect: overloads in classes can be inherited by subclasses;
381             overloads in roles will be incorporated into consuming classes.
382              
383             (See also L<MooseX::MarkAsMethods>)
384              
385             =head1 AVAILABLE OPTIONAL ATTRIBUTE TRAITS
386              
387             We export the following trait aliases. These traits are not
388             automatically applied to attributes, and are lazily loaded (e.g. if you don't
389             use them, they won't be loaded and are not dependencies).
390              
391             They can be used by specifying them as:
392              
393             has foo => (traits => [ TraitAlias ], ...);
394              
395             =head2 AutoDestruct
396              
397             has foo => (
398             traits => [ AutoDestruct ],
399             is => 'ro',
400             lazy => 1,
401             builder => 1,
402             ttl => 600,
403             );
404              
405             Allows for a "ttl" attribute option; this is the length of time (in seconds)
406             that a stored value is allowed to live; after that time the value is cleared
407             and the value rebuilt (given that the attribute is lazy and has a builder
408             defined).
409              
410             See L<MooseX::AutoDestruct> for more information.
411              
412             =head2 CascadeClearing
413              
414             This attribute trait allows one to designate that certain attributes are to be
415             cleared when certain other ones are; that is, when an attribute is cleared
416             that clearing will be cascaded down to other attributes. This is most useful
417             when you have attributes that are lazily built.
418              
419             See L<MooseX::CascadeClearing> for more information and a significantly more
420             cogent description.
421              
422             =head2 ENV
423              
424             This is a Moose attribute trait that you use when you want the default value
425             for an attribute to be populated from the %ENV hash. So, for example if you
426             have set the environment variable USERNAME to 'John' you can do:
427              
428             package MyApp::MyClass;
429              
430             use Moose;
431             use MooseX::Attribute::ENV;
432              
433             has 'username' => (is=>'ro', traits=>['ENV']);
434              
435             package main;
436              
437             my $myclass = MyApp::MyClass->new();
438              
439             print $myclass->username; # STDOUT => 'John';
440              
441             This is basically similar functionality to something like:
442              
443             has 'attr' => (
444             is=>'ro',
445             default=> sub {
446             $ENV{uc 'attr'};
447             },
448             );
449              
450             If the named key isn't found in %ENV, then defaults will execute as normal.
451              
452             See L<MooseX::Attribute::ENV> for more information.
453              
454             =head2 MultiInitArg
455              
456             has 'data' => (
457             traits => [ MultiInitArg ],
458             is => 'ro',
459             isa => 'Str',
460             init_args => [qw(munge frobnicate)],
461             );
462              
463             This trait allows your attribute to be initialized with any one of multiple
464             arguments to new().
465              
466             See L<MooseX::MultiInitArg> for more information.
467              
468             =head2 UndefTolerant
469              
470             Applying this trait to your attribute makes it's initialization tolerant of
471             of undef. If you specify the value of undef to any of the attributes they
472             will not be initialized (or will be set to the default, if applicable).
473             Effectively behaving as if you had not provided a value at all.
474              
475             package My:Class;
476             use Moose;
477              
478             use MooseX::UndefTolerant::Attribute;
479              
480             has 'bar' => (
481             traits => [ UndefTolerant ],
482             is => 'ro',
483             isa => 'Num',
484             predicate => 'has_bar'
485             );
486              
487             # Meanwhile, under the city...
488              
489             # Doesn't explode
490             my $class = My::Class->new(bar => undef);
491             $class->has_bar # False!
492              
493             See L<MooseX::UndefTolerant::Attribute> for more information.
494              
495             =head1 INCLUDED EXTENSIONS
496              
497             Reindeer includes the traits and sugar provided by the following extensions.
498             Everything their docs say they can do, you can do by default with Reindeer.
499              
500             =head2 L<MooseX::AbstractMethod>
501              
502             =head2 L<MooseX::AlwaysCoerce>
503              
504             =head2 L<MooseX::AttributeShortcuts>
505              
506             =head2 L<MooseX::ClassAttribute>
507              
508             =head2 L<MooseX::CurriedDelegation>
509              
510             =head2 L<MooseX::LazyRequire>
511              
512             =head2 L<MooseX::MarkAsMethods>
513              
514             Note that this causes any overloads you've defined in your class/role to be
515             marked as methods, and L<namespace::autoclean> invoked.
516              
517             =head2 L<MooseX::NewDefaults>
518              
519             =head2 L<MooseX::StrictConstructor>
520              
521             =head2 L<MooseX::Traits>
522              
523             This provides a new class method, C<with_traits()>, allowing you to compose
524             traits in on the fly:
525              
526             my $foo = Bar->with_traits('Stools')->new(...);
527              
528             =head1 INCLUDED TYPE LIBRARIES
529              
530             =head2 L<MooseX::Types::Moose>
531              
532             =head2 L<MooseX::Types::Common::String>
533              
534             =head2 L<MooseX::Types::Common::Numeric>
535              
536             =head2 L<MooseX::Types::LoadableClass>
537              
538             =head2 L<MooseX::Types::Path::Class>
539              
540             =head2 L<MooseX::Types::Tied::Hash::IxHash>
541              
542             =head1 OTHER
543              
544             Non-Moose specific items made available to your class/role:
545              
546             =head2 Perl v5.10 features
547              
548             If you're running on v5.10 or greater of Perl, Reindeer will automatically
549             enable v5.10 features in the consuming class.
550              
551             =head2 L<namespace::autoclean>
552              
553             Technically, this is done by L<MooseX::MarkAsMethods>, but it's worth pointing
554             out here. Any overloads present in your class/role are marked as methods
555             before autoclean is unleashed, so Everything Will Just Work as Expected.
556              
557             =head2 L<Path::Class>
558              
559             use Path::Class;
560            
561             my $dir = dir('foo', 'bar'); # Path::Class::Dir object
562             my $file = file('bob', 'file.txt'); # Path::Class::File object
563            
564             # Stringifies to 'foo/bar' on Unix, 'foo\bar' on Windows, etc.
565             print "dir: $dir\n";
566            
567             # Stringifies to 'bob/file.txt' on Unix, 'bob\file.txt' on Windows
568             print "file: $file\n";
569            
570             my $subdir = $dir->subdir('baz'); # foo/bar/baz
571             my $parent = $subdir->parent; # foo/bar
572             my $parent2 = $parent->parent; # foo
573            
574             my $dir2 = $file->dir; # bob
575              
576             # Work with foreign paths
577             use Path::Class qw(foreign_file foreign_dir);
578             my $file = foreign_file('Mac', ':foo:file.txt');
579             print $file->dir; # :foo:
580             print $file->as_foreign('Win32'); # foo\file.txt
581            
582             # Interact with the underlying filesystem:
583            
584             # $dir_handle is an IO::Dir object
585             my $dir_handle = $dir->open or die "Can't read $dir: $!";
586            
587             # $file_handle is an IO::File object
588             my $file_handle = $file->open($mode) or die "Can't read $file: $!";
589              
590             See the L<Path::Class> documentation for more detail.
591              
592             =head2 L<Try::Tiny>
593              
594             You can use Try::Tiny's C<try> and C<catch> to expect and handle exceptional
595             conditions, avoiding quirks in Perl and common mistakes:
596              
597             # handle errors with a catch handler
598             try {
599             die "foo";
600             } catch {
601             warn "caught error: $_"; # not $@
602             };
603              
604             You can also use it like a standalone C<eval> to catch and ignore any error
605             conditions. Obviously, this is an extreme measure not to be undertaken
606             lightly:
607              
608             # just silence errors
609             try {
610             die "foo";
611             };
612              
613             See the L<Try::Tiny> documentation for more detail.
614              
615             =head1 CAVEAT
616              
617             This author is applying his own assessment of "useful/popular extensions".
618             You may find yourself in agreement, or violent disagreement with his choices.
619             YMMV :)
620              
621             =head1 ACKNOWLEDGMENTS
622              
623             Reindeer serves largely to tie together other packages -- Moose extensions and
624             other common modules. Those other packages are largely by other people,
625             without whose work Reindeer would have a significantly smaller rack.
626              
627             We also use documentation as written for the other packages pulled in here to
628             help present a cohesive whole.
629              
630             =head1 SEE ALSO
631              
632             Please see those modules/websites for more information related to this module.
633              
634             =over 4
635              
636             =item *
637              
638             L<L<Moose>, and all of the above-referenced packages.|L<Moose>, and all of the above-referenced packages.>
639              
640             =back
641              
642             =head1 BUGS
643              
644             Please report any bugs or feature requests on the bugtracker website
645             L<https://github.com/RsrchBoy/reindeer/issues>
646              
647             When submitting a bug or request, please include a test-file or a
648             patch to an existing test-file that illustrates the bug or desired
649             feature.
650              
651             =head1 AUTHOR
652              
653             Chris Weyl <cweyl@alumni.drew.edu>
654              
655             =head1 CONTRIBUTOR
656              
657             =for stopwords Alex Balhatchet
658              
659             Alex Balhatchet <kaoru@slackwise.net>
660              
661             =head1 COPYRIGHT AND LICENSE
662              
663             This software is Copyright (c) 2017, 2015, 2014, 2012, 2011 by Chris Weyl.
664              
665             This is free software, licensed under:
666              
667             The GNU Lesser General Public License, Version 2.1, February 1999
668              
669             =cut