File Coverage

blib/lib/lib/with/preamble.pm
Criterion Covered Total %
statement 31 31 100.0
branch 6 8 75.0
condition 1 3 33.3
subroutine 10 10 100.0
pod 0 2 0.0
total 48 54 88.8


line stmt bran cond sub pod time code
1 1     1   15628 use strict;
  1         1  
  1         30  
2 1     1   4 use warnings;
  1         1  
  1         31  
3 1     1   3 #line 1
  1         10  
  1         23  
4 1     1   3 package lib::with::preamble;
  1         1  
  1         25  
5 1     1   6  
  1         2  
  1         16  
6 1     1   417 use strict;
  1         6598  
  1         258  
7             use warnings FATAL => 'all';
8             use File::Spec;
9             use PerlIO::via::dynamic;
10              
11 9     9 0 75858 our $VERSION = '0.001003'; # 0.1.3
12 9         23  
13 9         102 sub require_with_preamble {
14 9 100       4365 my ($arrayref, $filename) = @_;
15 1 50       24 my (undef, $preamble, @libs) = @$arrayref;
16 1         5 foreach my $cand (map File::Spec->catfile($_, $filename), @libs) {
17             if (-f $cand) {
18             if (open my $fh, '<', $cand) {
19             return with_preamble($preamble."\n#line 1 $cand\n", $fh);
20             }
21             }
22             }
23 1     1 0 2 }
24              
25 14 100   14   418 sub with_preamble {
26 1         10 my ($preamble, $fh) = @_;
27 1         390 PerlIO::via::dynamic->new(untranslate => sub {
28             $preamble and $_[1] =~ s/\A/$preamble/, undef($preamble);
29             })->via($fh);
30             return $fh;
31 1     1   7 }
32 1 50 33     8  
33 1         20 sub import {
34             my ($class, $preamble, @libs) = @_;
35             return unless defined($preamble) and @libs;
36             unshift @INC, [ \&require_with_preamble, $preamble, @libs ];
37             }
38              
39             1;
40              
41             =head1 NAME
42              
43             lib::with::preamble - invent your own default perl setup
44              
45             =head1 SYNOPSIS
46              
47             use lib::with::preamble 'use v5.16; use strictures 1;', 'lib';
48              
49             The above will load .pm files from lib/ - but they'll act as if your code
50             always started with 'use v5.16; use strictures 1;'.
51              
52             =head1 USING THIS IN A DISTRIBUTION
53              
54             To use this in a dist, you'll want to create two files -
55              
56             # my/lib.pm
57             use lib::with::preamble 'use v5.16; use strictures 1;', 'lib';
58             1;
59              
60             # my/filter
61             print "use v5.16;\nuse strictures 1;\n#line 1\n";
62             while () { print }
63              
64             and then tell your Makefile.PL to use the filter -
65              
66             WriteMakefile(
67             ...
68             PM_FILTER => 'perl my/filter'
69             );
70              
71             Then during development instead of doing
72              
73             $ perl -Ilib bin/script-to-test
74              
75             you'll want to do -
76              
77             $ perl -Mmy::lib bin/script-to-test
78              
79             and for prove -
80              
81             $ PERL5OPT=-Mmy::lib prove t/some-test.t
82              
83             but once you run
84              
85             $ make
86              
87             your blib/ will get populated with files that already have your
88             preamble added, so
89              
90             $ prove -b t/some-test.t
91              
92             will just work, as will
93              
94             $ make test
95              
96             and when your users install your module, the .pm files will already have
97             the preamble at the top, so your installed files will look like
98              
99             # My/Foo.pm
100             use v5.16;
101             use strictures 1;
102             # line 1
103             package My::Foo;
104             ...
105              
106             and everything should work, without you even needing to add this module
107             as a dependency.
108              
109             Patches to document an equivalent for those of you using L
110             (and L, even if I don't like the bedamned thing) would be
111             very welcome.
112              
113             =head1 WARNING
114              
115             This is as much a proof of concept as anything else at this point, so the
116             interface is NOT guaranteed to be stable. Especially since this is meant
117             to be a sort of implicit sugar, and history has proven that other people
118             are much better at designing APIs to sugar than I am.
119              
120             But provided you're using it the way I describe above, the my/filter script
121             isn't dependent on anything, so your users will be insulated from that.
122              
123             So please do have a play around and see if it works for you.
124              
125             =head1 AUTHOR
126              
127             mst - Matt S. Trout (cpan:MSTROUT)
128              
129             =head1 CONTRIBUTORS
130              
131             None yet. Well volunteered? :)
132              
133             =head1 COPYRIGHT
134              
135             Copyright (c) 2013 the lib::with::preamble L and L
136             as listed above.
137              
138             =head1 LICENSE
139              
140             This library is free software and may be distributed under the same terms
141             as perl itself.
142              
143             =cut