File Coverage

blib/lib/Data/Couplet/Extension.pm
Criterion Covered Total %
statement 8 10 80.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 12 14 85.7


line stmt bran cond sub pod time code
1 3     3   16 use strict;
  3         5  
  3         109  
2 3     3   14 use warnings FATAL => 'all';
  3         6  
  3         168  
3              
4             package Data::Couplet::Extension;
5             BEGIN {
6 3     3   179 $Data::Couplet::Extension::AUTHORITY = 'cpan:KENTNL';
7             }
8             {
9             $Data::Couplet::Extension::VERSION = '0.02004314';
10             }
11              
12             # ABSTRACT: A convenient way for sub classing Data::Couplet with minimal effort
13              
14 3     3   6058 use MooseX::Types::Moose qw( :all );
  0            
  0            
15             use Carp;
16              
17              
18             sub _dump {
19             my (@args) = @_;
20             require Data::Dumper;
21             local $Data::Dumper::Terse = 1;
22             local $Data::Dumper::Indent = 0;
23             local $Data::Dumper::Maxdepth = 1;
24             local $Data::Dumper::Quotekeys = 0;
25             return Data::Dumper::Dumper(@args);
26             }
27              
28             sub _carp_key {
29             my ( $key, $config, $message ) = @_;
30             carp( sprintf '%s => %s %s', $key, _dump( $config->{$key} ), $message );
31             return;
32             }
33              
34             sub _croak_key {
35             my ( $key, $config, $message ) = @_;
36             croak( sprintf '%s => %s %s', $key, _dump( $config->{$key} ), $message );
37             }
38              
39              
40             sub import {
41             my ( $class, @args ) = @_;
42             my (%config) = (@args);
43             my $caller = caller;
44              
45             require Moose;
46             require Data::Couplet::Private;
47             require Data::Couplet::Role::Plugin;
48              
49             $config{-into} = $caller unless exists $config{-into};
50              
51             #_croak_key( -into => \%config, 'target is not a valid ClassName' ) unless is_ClassName( $config{-into} );
52              
53             if ( $config{-into} eq 'main' ) {
54             _carp_key( -into => \%config, '<-- is main, not injecting' );
55             return;
56             }
57              
58             $config{-base} = q{} unless exists $config{-base};
59              
60             _croak_key( -base => \%config, 'is not a Str' ) unless is_Str( $config{-base} );
61              
62             $config{-base_package} = 'Data::Couplet';
63             if ( $config{-base} ne q{} ) {
64             $config{-base_package} = 'Data::Couplet::' . $config{-base};
65             }
66              
67             if ( $config{-base_package} eq 'Data::Couplet' ) {
68             require Data::Couplet;
69             }
70              
71             _croak_key( -base_package => \%config, 'is not a valid ClassName' )
72             unless is_ClassName( $config{-base_package} );
73              
74             $config{-with} = [] unless exists $config{-with};
75             $config{-with_expanded} = [];
76              
77             _croak_key( -with => \%config, 'is not an ArrayRef' ) unless is_ArrayRef( $config{-with} );
78             for ( @{ $config{-with} } ) {
79             my $plugin = 'Data::Couplet::Plugin::' . $_;
80             eval "require $plugin; 1" or croak("Could not load Data::Couplet plugin $plugin");
81             croak("plugin $plugin loaded, but still seems not to be a valid ClassName") unless is_ClassName($plugin);
82             croak("plugin $plugin cant meta") unless $plugin->can('meta');
83             croak("plugin $plugin meta cant does_role") unless $plugin->meta->can('does_role');
84             croak("plugin $plugin doesn't do DC::R:P") unless $plugin->meta->does_role('Data::Couplet::Role::Plugin');
85             push @{ $config{-with_expanded} }, $plugin;
86             }
87              
88             # Input validation and expansion et-all complete.
89             # Inject warnings/strict for caller.
90             strict->import();
91             warnings->import();
92             Moose->import( { into => $config{-into}, } );
93             $config{-into}->can('extends')->( $config{-base_package} );
94             $config{-into}->can('with')->( @{ $config{-with_expanded} } );
95             return;
96             }
97              
98              
99             sub unimport {
100              
101             # Sub Optimal, but cant be avoided atm because Moose lacks
102             # A 3rd-Party friendly unimport
103             goto \&Moose::unimport;
104             }
105              
106             1;
107              
108              
109             __END__
110             =pod
111              
112             =head1 NAME
113              
114             Data::Couplet::Extension - A convenient way for sub classing Data::Couplet with minimal effort
115              
116             =head1 VERSION
117              
118             version 0.02004314
119              
120             =head1 SYNOPSIS
121              
122             package My::DC;
123             use Data::Couplet::Extension -with [qw( Plugin )];
124             __PACKAGE__->meta->make_immutable;
125             1;
126              
127             This provides a handy way to subclass L<Data::Couplet>, glue a bunch of DC plug-ins into it, and just use it.
128              
129             The alternative ways, while working, are likely largely suboptimal ( applying roles to instances, yuck );
130              
131             This gives you an easy way to create a sub class of L<Data::Couplet>, and possibly tack on some of your own
132             methods directly.
133              
134             =head1 METHODS
135              
136             =head2 import
137              
138             Makes the calling package a Data::Couplet subclass.
139              
140             Data::Couplet::Extension->import(
141             -into => ( $target || caller ),
142             -base => ( $name || '' ),
143             -with => ( [qw( PluginA PluginB )] || [] ),
144             );
145              
146             =head3 -into => $target
147              
148             This is a convenience parameter, to make it easier to do via a 3rd party.
149              
150             If not set, its automatically set to C<scalar caller()>;
151              
152             =head3 -base => $name
153              
154             This is also mostly a convenience parameter, at this time, the only reason you'd want to set
155             this to something, would be if you wanted to extend the L<Data::Couplet::Private> core, and that's
156             recommended only for experts who don't like our interface.
157              
158             Incidentally, we use this to make Data::Couplet.
159              
160             =head3 -base_package => $name
161              
162             You can't set this yourself, we overwrite it, but this documentation is here to clarify how it works.
163              
164             This is the expansion of C<-base>. '' becomes 'Data::Couplet' ( which is the default ) and all other values
165             become 'Data::Couplet::' . $value;
166              
167             This is then used via L<Moose> C<extends> to define your packages base class.
168              
169             =head3 -with => [qw( name )]
170              
171             This one you probably want the most. Its semantically the same as Moose's C<with>, except that for convenience, all values of C<name> are expanded to C<Data::Couplet::name> and various tests are done on them to make sure they are compatible.
172              
173             You can leave this empty, but you're not maximising the point of this utility unless you fill it.
174              
175             =head3 -with_expanded => [qw( name )]
176              
177             You can't set this, we overwrite it. It gets populated from C<-with> by simple expansion, C<Data::Couplet::Plugin::$value>.
178              
179             These are fed to Moose's C<with> method on your package
180              
181             =head2 unimport
182              
183             Seeing the only things we import come from Moose anyway, this is just
184              
185             goto \&Moose::unimport;
186              
187             =head1 AUTHOR
188              
189             Kent Fredric <kentnl at cpan.org>
190              
191             =head1 COPYRIGHT AND LICENSE
192              
193             This software is copyright (c) 2011 by Kent Fredric.
194              
195             This is free software; you can redistribute it and/or modify it under
196             the same terms as the Perl 5 programming language system itself.
197              
198             =cut
199