File Coverage

blib/lib/rig.pm
Criterion Covered Total %
statement 30 30 100.0
branch 10 18 55.5
condition 3 9 33.3
subroutine 7 7 100.0
pod n/a
total 50 64 78.1


line stmt bran cond sub pod time code
1             package rig;
2             BEGIN {
3 6     6   88200 $rig::VERSION = '0.01_04';
4             }
5 6     6   34 use strict;
  6         10  
  6         98  
6 6     6   17 use Carp;
  6         5  
  6         2602  
7              
8             our %opts = (
9             engine => 'rig::engine::base',
10             parser => 'rig::parser::yaml',
11             );
12              
13             sub import {
14 11     11   246 my $class = shift;
15 11         26 my @args = $class->_process_pragmas(@_);
16 11 50 66     88 return if !@args and !exists $opts{'load'};
17              
18             # engine setup
19 8         16 my $foo = $class->_setup_engine;
20              
21             # parser setup
22 8         29 $class->_setup_parser;
23              
24             # go to the engine's import method
25 8 50       26 return unless @args;
26 8         83 my $instance = $opts{engine}->new(%opts);
27 8         49 @_ = ( $instance, @args );
28 8         37 goto &$foo;
29             }
30              
31             sub _process_pragmas {
32 11     11   12 my $class = shift;
33 11         11 my @args;
34 11         31 while ( local $_ = shift ) {
35 11 100       36 if (/^-(.+)$/) {
36              
37             # process pragma
38 3         3 my $next = shift;
39 3 50 33     20 unshift( @_, $next ), $next = undef
40             if defined $next && $next =~ /^-/;
41 3 50       13 $opts{$1} = defined $next ? $next : 1;
42             }
43             else {
44 8         20 push @args, $_;
45             }
46             }
47 11         24 return @args;
48             }
49              
50             sub _setup_engine {
51             $opts{engine} = shift || 'rig::engine::' . $opts{engine}
52 8 50 0 8   31 unless $opts{engine} =~ /\:\:/;
53 8 50       371 eval "require $opts{engine};" or croak "rig: " . $@;
54 8         36 return $opts{engine} . '::import';
55             }
56              
57             sub _setup_parser {
58             $opts{parser} = 'rig::parser::' . $opts{parser}
59 8 50   8   31 unless $opts{parser} =~ /\:\:/;
60 8 50       322 eval "require $opts{parser};" or croak "rig: " . $@;
61             }
62              
63             1;
64              
65             =head1 NAME
66              
67             rig - import groups of favorite/related modules with a single expression
68              
69             =head1 VERSION
70              
71             version 0.01_04
72              
73             =head1 SYNOPSIS
74              
75             In your C yaml file:
76              
77             common:
78             use:
79             - strict
80             - warnings
81             - List::Util:
82             - first
83             - max
84             - Data::Dumper
85              
86             Back in your code:
87              
88             use rig common;
89              
90             # same as:
91             # use strict;
92             # use warnings;
93             # use List::Util qw/first max/;
94             # use Data::Dumper;
95              
96             # now, have a ball:
97              
98             print first { $_ > 10 } @ary; # from List::Utils;
99             print Dumper $foo; # from Data::Dumper
100              
101             =head1 DESCRIPTION
102              
103             This module allows you to organize and bundle your favorite modules, thus reducing
104             the recurring task of Cing them in your programs, and implicitly requesting
105             imports by default.
106              
107             You can rig your bundles in 2 places:
108              
109             =over
110              
111             =item *
112              
113             A file called C<.perlrig> in your home or current working directory.
114              
115             =item *
116              
117             Packages undeneath the C>, for better portability.
118              
119             =back
120              
121             =head1 IMPLEMENTATION
122              
123             This module uses lots of internal Cs to trick modules to think they're being
124             loaded by the original caller, and not by C itself. It also hooks into C to keep
125             modules loading after a C.
126              
127             Modules that don't have an C method, are instead Cled into the caller's package.
128              
129             This is somewhat hacky, there are probably better ways of achieving the same results.
130             We're open to suggestions on how to make loading modules more generic and effective.
131              
132             =head1 USAGE
133              
134             =head2 Code
135              
136             use rig -file => '/tmp/.rig'; # explicitly use a file
137             use rig -engine => 'base';
138             use rig -path => qw(. /home/me /opt); # not implemented yet
139             use rig -jit => 1; # not implemented yet
140              
141             use rig moose, strictness, modernity;
142              
143             use rig 'kensho';
144             use rig 'kensho::strictive'; # looks for rig::task::kensho::strictive
145             use rig 'signes';
146              
147             =head2 C<.perlrig> YAML structure
148              
149             :
150             use:
151             - [min_version]
152             - +
153             - :
154             -
155             -
156             - ...
157             also: [, ... ]
158              
159             =head3 use section
160              
161             =over
162              
163             =item *
164              
165             Lists modules to be Cd.
166              
167             =item *
168              
169             Checks module versions (optional).
170              
171             =item *
172              
173             Lists exports (optional).
174              
175             =back
176              
177             By default, modules are imported by calling C. Alternatively,
178             a plus sign C<+> can be used in front of the module to force
179             it to be loaded using the C method, as such:
180              
181             eval "package ; use ;"
182              
183             This may be useful to workaround issues with using import when
184             none is available, or things are just not working as expected.
185              
186             =head3 also section
187              
188             Used to bundle tasks into each other.
189              
190             =head3 Examples
191              
192             moose:
193             use:
194             - Moose 0.92
195             - Moose::Autobox
196             - autodie
197             - Method::Signatures
198             - Try::Tiny
199             goo:
200             use:
201             - strict
202             - warnings
203             - Data::Dumper
204             - feature:
205             - say
206             - switch
207             - Data::Alias
208             - autodie
209             bam:
210             use:
211             - List::Util:
212             - first
213             - max
214             - min
215             - Scalar::Util:
216             - refaddr
217             - Carp:
218             - cluck
219             - croak
220              
221             =head1 The .perlrig file
222              
223             The .perlrig file is where you keep your favorite rigs.
224              
225             As mentioned earlier, C looks for a C<.perlrig> file in two
226             directories by default:
227              
228             * The current working directory.
229             * Your home directory.
230              
231             Important: only one rig file is loaded per C interpreter
232             instance. This will probably change in the future, as C<.perlrig>
233             file merging should be implemented.
234              
235             =head2 Structure
236              
237             It could have had room to put your funky startup code, but
238             it doesn't. This module is about order and parseability.
239              
240             Having a structured file written in plain yaml makes it easier for worldly parsers
241             to parse the file and understand your configuration.
242              
243             =head2 Writing your own parser
244              
245             Although this distribution only comes with a yaml parser for the .perlrig file.
246             you can still write your own parser if you like:
247              
248             package rig::parser::xml;
249             use base 'rig::parser::base';
250              
251             sub parse { return .... }
252              
253             # meanwhile in Gotham City:
254              
255             package main;
256             use rig -parser => 'xml';
257             use rig 'fav-in-xml';
258              
259             =head2 Global Configuration
260              
261             Use the C<$ENV{PERLRIG_FILE}> variable to tell C where to find your file.
262              
263             $ export PERLRIG_FILE=/etc/myrig
264             $ perl foo_that_rigs.pl
265            
266             =head1 rig::task:: modules
267              
268             A more distribution-friendly way of wiring up module bundles for your application is
269             to ship them as part of the C namespace.
270              
271             package rig::task::myfav;
272              
273             sub rig {
274             return {
275             use => [
276             'strict',
277             { 'warnings'=> [ 'FATAL','all' ] }
278             ],
279             also => 'somethingelse',
280             };
281             }
282              
283             This is the recommended way to ship a rig with your distribution. It
284             makes your distribution portable, no C<.perlrig> file is required.
285              
286             =head1 CAVEATS
287              
288             Although short, the api and yaml specs are still unstable and are
289             subject to change. Mild thought has been put into it as to support
290             modifications without major deprecations.
291              
292             =head2 Startup Cost
293              
294             There's an upfront load time (on the first C it finds) while C
295             looks for, parses and processes your C<.perlrig> file. Subsequent calls
296             won't look for any more files, as its structure will remain loaded in memory.
297              
298             =head2 Ordered Load
299              
300             As of right now, module loading order tends to get messed up easily. This
301             will probably be fixed, as the author's intention is to load modules
302             following the order set by the user in the C<.perlrig> and C
303             statements.
304              
305             =head1 ON NAMING THIS PACKAGE
306              
307             The authors feel that C is a short name that is good for one-liners.
308             It's lowercase because we feel it's a pragma-like module that augments
309             the functionality of C.
310             But C is a unique enough name as to avoid
311             clashing with future Perl pragmas.
312              
313             We're sorry if it hurts anyone's lowercase sensibility.
314              
315             =head1 TODO
316              
317             =over
318              
319             =item *
320              
321             Create a class to hold the perlrig definition.
322              
323             =item *
324              
325             Use L or similar for more agnostic and advanced file loading.
326              
327             =item *
328              
329             Straighten out and optimize internals.
330              
331             =item *
332              
333             Test many more modules for edge cases.
334              
335             =item *
336              
337             More verbs besides C and C, such as require, etc.
338              
339             =item *
340              
341             A cookbook of some sort, with everyday examples.
342              
343             =item *
344              
345             More tests.
346              
347             =item *
348              
349             Fix load sequence.
350              
351             =back
352              
353             =head1 SEE ALSO
354              
355             L - uses filters and C to accomplish its import magic.
356              
357             L - employs C and C.
358              
359             =cut