File Coverage

blib/lib/Reindeer.pm
Criterion Covered Total %
statement 38 38 100.0
branch 3 16 18.7
condition n/a
subroutine 9 9 100.0
pod 0 1 0.0
total 50 64 78.1


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