File Coverage

blib/lib/perl5i/2.pm
Criterion Covered Total %
statement 74 76 97.3
branch 15 18 83.3
condition 5 5 100.0
subroutine 16 16 100.0
pod 0 6 0.0
total 110 121 90.9


line stmt bran cond sub pod time code
1             # vi: set ts=4 sw=4 ht=4 et :
2             package perl5i::2;
3              
4 103     103   211919 use 5.010;
  103         691  
  103         10216  
5              
6 103     103   582 use strict;
  103         209  
  103         4973  
7 103     103   574 use warnings;
  103         191  
  103         4436  
8              
9             #This should come first
10 103     103   77636 use perl5i::2::RequireMessage;
  103         259  
  103         3382  
11              
12 103     103   155604 use Carp::Fix::1_25;
  103         137734  
  103         13542  
13 103     103   67149 use perl5i::2::autobox;
  103         424  
  103         1810  
14              
15 103     103   83544 use perl5i::VERSION; our $VERSION = perl5i::VERSION->VERSION;
  103         263  
  103         168176  
16              
17             our $Latest = perl5i::VERSION->latest;
18              
19             my %Features = (
20             # A stub for autodie. It's handled specially in import().
21             autodie => sub {},
22             autobox => sub {
23             my ($class, $caller) = @_;
24              
25             perl5i::2::autobox::import($class);
26             },
27             autovivification => sub {
28             my ($class, $caller) = @_;
29              
30             # no autovivification;
31             require autovivification;
32             autovivification::unimport($class);
33             },
34             capture => sub {
35             my ($class, $caller) = @_;
36             (\&capture)->alias($caller, "capture");
37             },
38             "Carp::Fix::1_25" => sub {
39             my ($class, $caller) = @_;
40             load_in_caller($caller, ["Carp::Fix::1_25"]);
41             },
42             Child => sub {
43             my ($class, $caller) = @_;
44             load_in_caller($caller, ['Child' => qw(child)]);
45             },
46             CLASS => sub {
47             my ($class, $caller) = @_;
48             load_in_caller($caller, ['CLASS']);
49             },
50             die => sub {
51             my ($class, $caller) = @_;
52             (\&perl5i_die)->alias($caller, "die");
53             },
54             English => sub {
55             my ($class, $caller) = @_;
56             load_in_caller($caller, ['English' => qw(-no_match_vars)]);
57             },
58             'File::chdir' => sub {
59             my ($class, $caller) = @_;
60             load_in_caller($caller, ['File::chdir']);
61             },
62             indirect => sub {
63             my ($class, $caller) = @_;
64              
65             # no indirect ':fatal'
66             require indirect;
67             indirect::unimport($class, ":fatal");
68             },
69             list => sub {
70             my ($class, $caller) = @_;
71             (\&force_list_context)->alias($caller, 'list');
72             },
73             Meta => sub {
74             require perl5i::2::Meta;
75             },
76             'Modern::Perl' => sub {
77             my ($class, $caller) = @_;
78              
79             # use Modern::Perl
80             require Modern::Perl;
81             Modern::Perl::import($caller);
82              
83             # no strict vars for oneliners - GH #63
84             strict::unimport($class, 'vars')
85             if $class eq 'perl5i::cmd'
86             or $0 eq '-e';
87              
88             # Modern::Perl won't pass this through to our caller.
89             require mro;
90             mro::set_mro($caller, 'c3');
91             },
92             'Perl6::Caller' => sub {
93             my ($class, $caller) = @_;
94             load_in_caller($caller, ['Perl6::Caller']);
95             },
96             Signatures => sub {
97             my ($class, $caller) = @_;
98             load_in_caller($caller, ['perl5i::2::Signatures']);
99             },
100             stat => sub {
101             my ($class, $caller) = @_;
102              
103             require File::stat;
104             # Export our stat and lstat
105             (\&stat)->alias($caller, 'stat');
106             (\&lstat)->alias($caller, 'lstat');
107             },
108             time => sub {
109             my ($class, $caller) = @_;
110              
111             require perl5i::2::DateTime;
112             # Export our gmtime() and localtime()
113             (\&perl5i::2::DateTime::dt_gmtime)->alias($caller, 'gmtime');
114             (\&perl5i::2::DateTime::dt_localtime)->alias($caller, 'localtime');
115             (\&perl5i::2::DateTime::dt_time)->alias($caller, 'time');
116             },
117             true => sub {
118             my ($class, $caller) = @_;
119              
120             # use true
121             require true;
122             true::import($class);
123             },
124             'Try::Tiny' => sub {
125             my ($class, $caller) = @_;
126             load_in_caller($caller, ['Try::Tiny']);
127             },
128             'utf8::all' => sub {
129             my ($class, $caller) = @_;
130              
131             # use utf8::all
132             require utf8::all;
133             utf8::all::import($class);
134             },
135             Want => sub {
136             my ($class, $caller) = @_;
137             load_in_caller($caller, ['Want' => qw(want)]);
138             },
139             );
140              
141             # This is necessary for autodie to work and be lexical
142 103     103   840 use parent 'autodie';
  103         323  
  103         1895  
143              
144             ## no critic (Subroutines::RequireArgUnpacking)
145             sub import {
146 115     115   4333 my $class = shift;
147 115         319 my %import = @_;
148              
149 115         451 my $caller = caller;
150              
151             # Read the skip list and turn it into a hash
152 115   100     1680 my $skips = delete $import{-skip} || [];
153 115         386 $skips = { map { $_ => 1 } @$skips };
  3         15  
154              
155             # Any remaining import parameters are unknown
156 115 100       657 if( keys %import ) {
157 1         164 croak sprintf "Unknown parameters '%s' in import list",
158 1         4 join(", ", map { "$_ => $import{$_}" } keys %import);
159             }
160              
161             # Check all the skipped features are valid
162 114         483 for my $f ( grep { !exists $Features{$_} } keys %$skips ) {
  3         20  
163 1         278 croak "Unknown feature '$f' in skip list";
164             }
165              
166             # Current lexically active major version of perl5i.
167 113         686 $^H{perl5i} = 2;
168              
169             # Load all the features.
170 113         842 for my $feature (keys %Features) {
171 2486 100       984517 next if $skips->{$feature};
172 2484         10647 $Features{$feature}->($class, $caller);
173             }
174              
175             # autodie needs a bit more convincing
176 113 100       64998 if( !$skips->{autodie} ) {
177 112         730 @_ = ( $class, ":all" );
178 112         1346 goto &autodie::import;
179             }
180             }
181              
182 1     1   438613 sub unimport { $^H{perl5i} = 0 }
183              
184             # fix die so that it always returns 255
185             sub perl5i_die {
186             # Leave a single ref be
187 21     21 0 2703187 local $! = 255;
188 21 100 100     199 return CORE::die(@_) if @_ == 1 and ref $_[0];
189              
190 18         50 my $error = join '', @_;
191 18 100       80 unless ($error =~ /\n$/) {
192 15         44 my ($file, $line) = (caller)[1,2];
193 15         50 $error .= " at $file line $line.\n";
194             }
195              
196 18         200 local $! = 255;
197 18         117 return CORE::die($error);
198             }
199              
200              
201             sub load_in_caller {
202 1016     1016 0 2431 my $caller = shift;
203 1016         2592 my @modules = @_;
204              
205 1016         2368 for my $spec (@modules) {
206 1016         2378 my( $module, @args ) = @$spec;
207              
208 1016         12045 $module->require;
209             ## no critic (BuiltinFunctions::ProhibitStringyEval)
210 1016 50       3296879 eval qq{
211             package $caller;
212             \$module->import(\@args);
213             1;
214             } or die "Error while perl5i loaded $module => @args: $@";
215             }
216              
217 1016         6023 return;
218             }
219              
220              
221             # File::stat does not play nice in list context
222             sub stat {
223 3 100   3 0 3093 return CORE::stat(@_) if wantarray;
224 2         18 return File::stat::stat(@_);
225             }
226              
227             sub lstat {
228 1 50   1 0 30 return CORE::lstat(@_) if wantarray;
229 0         0 return File::stat::lstat(@_);
230             }
231              
232              
233             sub capture(&;@) {
234 16     16 0 4528512 my($code, %opts) = @_;
235              
236             # valid options
237 16         91 state $valid_options = { map { $_ => 1 } qw(merge tee) };
  6         46  
238              
239 16         120 for my $key (keys %opts) {
240 2 50       16 croak "$key is not a valid option to capture()" unless $valid_options->{$key};
241             }
242              
243 16         91 my $opts = join "/", sort { $a cmp $b } grep { $opts{$_} } keys %opts;
  0         0  
  2         20  
244              
245             # Translate option combinations into Capture::Tiny functions
246 16         6244 require Capture::Tiny;
247 16         229331 state $captures = {
248             "" => \&Capture::Tiny::capture,
249             "tee" => \&Capture::Tiny::tee,
250             "merge" => \&Capture::Tiny::capture_merged,
251             "merge/tee" => \&Capture::Tiny::tee_merged
252             };
253              
254 16         67 my $func = $captures->{$opts};
255 16         631 return $func->($code);
256             }
257              
258              
259             sub force_list_context(@) {
260 6     6 0 7017 return @_;
261             }
262              
263             1;