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