File Coverage

blib/lib/filename.pm
Criterion Covered Total %
statement 28 29 96.5
branch 11 16 68.7
condition 3 9 33.3
subroutine 6 6 100.0
pod 1 1 100.0
total 49 61 80.3


line stmt bran cond sub pod time code
1              
2 1     1   459 use strict;
  1         2  
  1         25  
3 1     1   4 use warnings;
  1         2  
  1         23  
4              
5 1     1   381 use locale; # localize $!
  1         488  
  1         5  
6              
7             package filename;
8             # ABSTRACT: Perl module to load files at compile-time, without BEGIN blocks.
9              
10              
11 1     1   39 use Carp 1.50 ();
  1         17  
  1         16  
12 1     1   4 use File::Spec ();
  1         1  
  1         426  
13              
14              
15             our $VERSION = 'v0.20.010'; # VERSION
16              
17              
18              
19             my ( $do, $error ) = (); # Private subs
20              
21             # Modified version of the code as specified in `perldoc -f require`
22             *import = \&require;
23             sub require {
24 54 50 33 54 1 789296 eval { $_[0]->isa(__PACKAGE__) } && shift
  54         412  
25             || Carp::croak( $_[0], " is not a ", __PACKAGE__ );
26 54 100       135 my $filename = @_ ? shift : $_;
27 54 50       105 Carp::croak("Null filename used") unless length($filename);
28              
29 54 100       257 return $INC{$filename} if ( exists $INC{$filename} );
30              
31 39 100       282 if ( File::Spec->file_name_is_absolute($filename) ) {
32 19 50 33     205 goto NOT_INC if $^V < v5.17.0 && !-r $filename;
33 19         68 return $do->($filename);
34             }
35 20         43 foreach my $inc (@INC) {
36 20         31 my $prefix = $inc;
37             #if ( my $ref = ref($inc) ) {
38             # # TODO ...
39             #}
40 20 50       450 next unless -f ( my $fullpath = "$prefix/$filename" );
41 20 50 33     260 next if $^V < v5.17.0 && !-r _;
42 20         69 return $do->( $fullpath => $filename );
43             }
44             NOT_INC:
45 0           Carp::croak("Can't locate $filename in \@INC (\@INC contains: @INC)");
46             }
47              
48             my $do_text = <<'END';
49             package $pkg;
50             my $result = do($fullpath);
51             die $@ if $@;
52             $INC{$filename} = delete $INC{$fullpath}
53             if $filename ne $fullpath && exists $INC{$fullpath};
54             $result;
55             END
56             $do = sub {
57             my $fullpath = @_ ? shift : $_;
58             my $filename = @_ ? shift : $fullpath;
59             my ($pkg) = caller(2);
60              
61             ( my $do_eval = $do_text ) =~ s/\$pkg/$pkg/;
62             return eval $do_eval || $error->( $filename => $fullpath );
63             };
64              
65             # Private sub
66             $error = sub {
67             my $filename = @_ ? shift : $_;
68             my $fullpath = @_ ? shift : $filename;
69              
70             $INC{$filename} &&= undef($!); # $! is invalid if $INC{$filename} is true.
71              
72             $@ && Carp::croak( $@, "Compilation failed in require" );
73              
74             $! && Carp::croak(
75             "Can't locate $filename: ",
76             $^V >= v5.21.0 ? "$fullpath: " : (),
77             "$!"
78             );
79              
80             Carp::croak( $filename, " did not return a true value" );
81             };
82              
83             1;
84              
85             __END__