File Coverage

blib/lib/Import/These.pm
Criterion Covered Total %
statement 54 57 94.7
branch 27 30 90.0
condition 6 8 75.0
subroutine 6 6 100.0
pod n/a
total 93 101 92.0


line stmt bran cond sub pod time code
1             package Import::These;
2              
3 11     11   771684 use strict;
  11         117  
  11         319  
4 11     11   56 use warnings;
  11         21  
  11         314  
5 11     11   55 use feature "say";
  11         20  
  11         2261  
6              
7              
8             our $VERSION = 'v0.1.2';
9              
10             # Marker is pushed to end of argument list to aid in processing.
11             # Make random to prevent collisions.
12             #
13             my $marker=join "", map int rand 26, 1..16;
14              
15              
16             sub import {
17 11     11   89 no strict "refs";
  11         20  
  11         6848  
18              
19 13     13   178 my $package=shift;
20              
21 13         25 my $prefix="";
22 13         27 my $next_prefix="";
23 13         67 my $k;
24             my $version;
25 13         0 my $mod;
26 13         0 my $next_mod;
27 13         0 my $list;
28              
29              
30 13         39 push @_, $marker;
31            
32             # Save the target export level
33 13   50     99 my $target_level=($Exporter::ExportLevel||0)+1;
34              
35 13         22 my $i=0;
36 13         65 while(@_){
37 44         70 $k=shift;
38              
39             # Check if the next item is a ref, or a scalar
40             #
41 44         88 my $r=ref $k;
42 44 100       123 if($r eq "ARRAY"){
    50          
43 7         31 $list=$k;
44             }
45              
46             elsif($r eq ""){
47 37 100       203 if($k eq $marker){
    100          
    100          
    100          
    100          
48             }
49             elsif($k eq "::"){
50             # Exact. Clear prefix
51 1         1 $next_prefix="";
52             }
53             elsif($k =~ /^::.*?::$/){
54             # Double ended. Append new portion to prefix
55 2         8 $next_prefix=$prefix.substr $k, 2;
56             }
57             elsif($k =~/::$/){
58             # At end. Update prefix
59 7         17 $next_prefix=$k;
60             }
61             elsif($k =~ /^v|^\d/){
62             # Test if it looks like a version.
63 4 100       13 unless($i){
64             # Actually a perl version
65 1     1   77 eval "use $k";
  1         36  
  0            
66 1 50       1346 die $@ if $@;
67 0         0 next;
68             }
69             else {
70 3         6 $version=$k;
71             }
72             }
73             else {
74             # Module name
75 12         29 $next_mod=$k;
76             }
77             }
78             else {
79 0         0 die "Scalar or array ref only";
80             }
81              
82             # Attempt to execute/load the current state
83            
84 43 100       91 if($mod){
85             #say STDERR "REQUIRE $prefix$mod";
86             # Force export level to 0 so any imports of required package are
87             # relative to required package
88 12         23 local $Exporter::ExportLevel=0;
89 12         800 eval "require $prefix$mod;";
90 12 50       13191 die "Could not require $prefix$mod: $@" if $@;
91              
92             # After the package has been required, set the target level for import
93             #
94 12         30 local $Exporter::ExportLevel=$target_level;
95              
96 12 100       36 if($version){
97 3         1409 "$prefix$mod"->VERSION($version);
98             }
99              
100 11 100 100     93 if($list and @$list){
    100 66        
101             # List import
102 5         166 "$prefix$mod"->import(@$list);
103             }
104             elsif($list and @$list ==0){
105             # no not import
106             }
107             else {
108             # Default import
109 5         221 "$prefix$mod"->import();
110             }
111             }
112            
113             # Update the state
114 42         86 $mod=$next_mod;
115              
116 42         60 $next_mod=undef;
117 42 100       84 $prefix=$next_prefix if $next_prefix;
118 42         62 $next_prefix=undef;
119 42         58 $list=undef;
120 42         58 $version=undef;
121 42         12571 $i++;
122             }
123             }
124              
125             __PACKAGE__;
126              
127             =head1 NAME
128              
129             Import::These - Terse, Prefixed and Multiple Imports with a Single Statement
130              
131             =head1 SYNOPSIS
132              
133             Any item ending with :: is a prefix. Any later items in the list will use the
134             prefix to create the full package name:
135              
136             #Instead of this:
137             #
138             use Plack::Middleware::Session;
139             use Plack::Middleware::Static;
140             use Plack::Middleware::Lint;
141             use IO::Compress::Gzip;
142             use IO::Compress::Gunzip;
143             use IO::Compress::Deflate;
144             use IO::Compress::Inflate;
145              
146              
147             # Do this
148             use Import::These qw<
149             Plack::Middleware:: Session Static Lint
150             IO::Compress:: Gzip GunZip Defalte Inflate
151             >;
152              
153              
154              
155             Any item exactly equal to :: clears the prefix:
156              
157             use Import::These "Prefix::", "Mod", "::", "Prefix::Another";
158             # Prefix::Mod
159             # Prefix::Another;
160              
161              
162             A item beginning with :: and ending with :: appends the item to the prefix:
163              
164             use Import::These "Plack::", "Test", "::Middleware::", "Lint";
165             # Plack::Test,
166             # Plack::Middleware::Lint;
167              
168              
169             Supports default, named/tagged, and no import:
170              
171             # Instead of this:
172             #
173             # use File::Spec::Functions;
174             # use File::Spec::Functions "catfile";
175             # use File::Spec::Functions ();
176              
177             # Do This:
178             #
179             use Import::These "File::Spec::", Functions,
180             Functions=>["catfile"],
181             Functions=>[]
182              
183             Supports Perl Version as first argument to list
184              
185             use Import::These qw;
186             # use v5.36;
187             # Plack::Test,
188             # Plack::Middleware::Lint;
189              
190             Supports Module Version
191              
192             use Import::These qw;
193             # use File::Spec::Functions 1.3;
194             #
195             use Import::These qw, ["catfile"];
196             # use File::Spec::Functions 1.3 "catfile";
197            
198             =head1 DESCRIPTION
199              
200             A tiny module for importing multiple modules in one statement utilising a
201             prefix. The prefix can be set, cleared, or appended multiple times in a list,
202             making long lists of imports much easier to type!
203              
204             It works with any package providing a C subroutine (i.e. compatible
205             with L. It also is compatible with recursive exporters such as
206             L manipulating the export levels.
207              
208              
209             =head1 USAGE
210              
211             When using this pragma, the list of arguments are interpreted as either a Perl
212             version, prefix mutation, module name, module version or array ref of symbols
213             to import. The current value of the prefix is applied to module names as they
214             appear in the list.
215              
216              
217             =over
218              
219             =item The prefix always starts out as an empty string.
220              
221             =item The first item in the list is optionally a Perl version
222              
223             =item Module version optionally comes after a module name (prefixed or not)
224              
225             =item Symbols list optionally comes after a module name or module version if used
226              
227             =item The prefix can be set/cleared/appended as many times as needed
228              
229             =back
230              
231             =head2 Prefix Manipulation
232              
233             The current prefix is used for all module names as they occur. However, changes
234             to the prefix can be interleaved within module names.
235              
236              
237             =head3 Set the Prefix
238              
239             Name::
240              
241             # Prefix equals "Name::"
242              
243             Any item in the list ending in "::" with result in the prefix being set to item (including the ::)
244              
245             =head3 Append The Prefix
246              
247             ::Name::
248              
249             # Prefix equals "OLDPREFIX::Name::"
250            
251             Any item in the list starting and ending with "::" will result in the prefix
252             having the item appended to it. The item has the leading "::" removed before
253             appending.
254              
255              
256             =head3 Clear the Prefix
257              
258             ::
259            
260             #Prefix is ""
261            
262             Any item in the list equal to "::" exactly will clear the prefix to an empty
263             string
264              
265             =head1 EXAMPLES
266              
267             The following examples make it easier to see the benefits of using this module:
268              
269             =head2 Simple Prefix
270              
271             A single prefix used for multiple packages:
272              
273             use Import::These qw;
274              
275             # Equivalent to:
276             # use IO::Compress::Gzip
277             # use IO::Compress::GunZip
278             # use IO::Compress::Deflate
279             # use IO::Compress::Inflate
280              
281             =head2 Appending Prefix
282              
283             Prefix is appended along the way:
284              
285             use Import::These qw;
286            
287             # Equivalent to:
288             # use IO::File
289             # use IO::Compress::Gzip
290             # use IO::Compress::GunZip
291             # use IO::Compress::Deflate
292             # use IO::Compress::Inflate
293              
294             =head2 Reset Prefix
295              
296             Completely change (reset) prefix to something else:
297              
298             use Import::These qw;
299              
300             # Equivalent to:
301             # use File::Spec::Functions
302             # use IO::Compress::Gzip
303             # use IO::Compress::GunZip
304             # use IO::Compress::Deflate
305             # use IO::Compress::Inflate
306              
307              
308             =head2 No Default Import
309              
310             use Import::These "File::Spec::", "Functions"=>[];
311              
312             # Equivalent to:
313             # use File::Spec::Functions ();
314            
315             =head2 Import Names/groups
316              
317             use Import::These "File::Spec::", "Functions"=>["catfile"];
318              
319             # Equivalent to:
320             # use File::Spec::Functions ("catfile");
321              
322              
323             =head2 With Perl Version
324              
325             use Import::These "v5.36", "File::Spec::", "Functions";
326              
327             # Equivalent to:
328             # use v5.36;
329             # use File::Spec::Functions;
330              
331             =head2 With Module Version
332              
333             use Import::These "File::Spec::", "Functions", "v1.2";
334              
335             # Equivalent to:
336             # use File::Spec::Functions v1.2;
337              
338              
339             =head2 All Together Now
340              
341             use Import::These qw, ["catfile"], qw<:: IO::Compress:: Gzip GunZip Deflate Inflate>;
342              
343             # Equivalent to:
344             # use v5.36;
345             # use File::IO;
346             # use File::Spec::Functions v1.2 "catfile"
347             # use IO::Compress::Gzip;
348             # use IO::Compress::GunZip;
349             # use IO::Compress::Deflate;
350             # use IO::Compress::Inflate;
351              
352              
353             =head1 COMPARISON TO OTHER MODULES
354              
355             L Performs can perform multiple imports, however requires a
356             custom package to group the imports and reexport them. Does not support
357             prefixes.
358              
359             L is very similar however does not support prefixes.
360              
361              
362             L works by loading ALL packages under a common prefix. Whether you need
363             them or not. That could be a lot of disk access and memory usage.
364              
365             L has automatic module installation using CPAN. However no
366             prefix support and uses B of RAM for basic importing
367              
368             L has some nice features but not a 'simple' package prefix. It also
369             looks like it only handles a single package per invocation
370              
371             =head1 REPOSITOTY and BUGS
372              
373             Please report and feature requests or bugs via the github repo:
374              
375             L
376              
377             =head1 AUTHOR
378              
379             Ruben Westerberg, Edrclaw@mac.comE
380              
381             =head1 COPYRIGHT AND LICENSE
382              
383             Copyright (C) 2023 by Ruben Westerberg
384              
385             Licensed under MIT
386              
387             =head1 DISCLAIMER OF WARRANTIES
388              
389             THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
390             INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
391             FITNESS FOR A PARTICULAR PURPOSE.
392              
393             =cut
394            
395