File Coverage

blib/lib/Importer/Zim/Unit.pm
Criterion Covered Total %
statement 27 33 81.8
branch 1 6 16.6
condition 0 3 0.0
subroutine 9 10 90.0
pod 0 1 0.0
total 37 53 69.8


line stmt bran cond sub pod time code
1              
2             package Importer::Zim::Unit;
3             $Importer::Zim::Unit::VERSION = '0.4.0';
4             # ABSTRACT: Import functions with compilation unit scope
5              
6 2     2   46814 use 5.010001;
  2         22  
7              
8             BEGIN {
9 2     2   501 require Importer::Zim::Base;
10 2         7192 Importer::Zim::Base->VERSION('0.8.0');
11 2         51 our @ISA = qw(Importer::Zim::Base);
12             }
13              
14 2     2   489 use Devel::Hook ();
  2         1381  
  2         40  
15 2     2   494 use Sub::Replace ();
  2         2160  
  2         46  
16              
17 2     2   12 use Importer::Zim::Utils 0.8.0 qw(DEBUG carp);
  2         26  
  2         10  
18              
19             sub import {
20 1     1   8 my $class = shift;
21              
22 1         2 carp "$class->import(@_)" if DEBUG;
23 1         6 my @exports = $class->_prepare_args(@_);
24              
25 1         217 my $caller = caller;
26             return _export_to( #
27 1         2 map { ; "${caller}::$_->{export}" => $_->{code} } @exports
  2         6  
28             );
29             }
30              
31             sub export_to {
32 0     0 0 0 my $t = shift;
33 0 0 0     0 @_ = %{ $_[0] } if @_ == 1 && ref $_[0] eq 'HASH';
  0         0  
34 0 0       0 @_ = map { $_ & 1 ? $_[$_] : "${t}::$_[$_]" } 0 .. $#_;
  0         0  
35 0         0 goto &_export_to;
36             }
37              
38             sub _export_to {
39 1     1   3 my $old = Sub::Replace::sub_replace(@_);
40              
41             # Clean it up after compilation
42             Devel::Hook->unshift_UNITCHECK_hook(
43             sub {
44 1     1   630 warn qq{ Restoring @{[map qq{"$_"}, sort keys %$old]}\n}
45             if DEBUG;
46 1         3 Sub::Replace::sub_replace($old);
47             }
48 1 50       241 ) if %$old;
49             }
50              
51 2     2   530 no Importer::Zim::Utils qw(DEBUG carp);
  2         3  
  2         6  
52              
53             1;
54              
55             #pod =encoding utf8
56             #pod
57             #pod =head1 SYNOPSIS
58             #pod
59             #pod use Importer::Zim::Unit 'Scalar::Util' => 'blessed';
60             #pod use Importer::Zim::Unit 'Scalar::Util' =>
61             #pod ( 'blessed' => { -as => 'typeof' } );
62             #pod
63             #pod use Importer::Zim::Unit 'Mango::BSON' => ':bson';
64             #pod
65             #pod use Importer::Zim::Unit 'Foo' => { -version => '3.0' } => 'foo';
66             #pod
67             #pod use Importer::Zim::Unit 'SpaceTime::Machine' => [qw(robot rubber_pig)];
68             #pod
69             #pod =head1 DESCRIPTION
70             #pod
71             #pod "I'm gonna roll around on the floor for a while. KAY?"
72             #pod – GIR
73             #pod
74             #pod This is a backend for L which makes imported
75             #pod symbols available during compilation.
76             #pod
77             #pod Unlike L, it works for perls before 5.18.
78             #pod Unlike L which plays with lexical subs,
79             #pod this meddles with the symbol tables for a (hopefully short)
80             #pod time interval.
81             #pod
82             #pod =head1 HOW IT WORKS
83             #pod
84             #pod The statement
85             #pod
86             #pod use Importer::Zim::Unit 'Foo' => 'foo';
87             #pod
88             #pod works sort of
89             #pod
90             #pod use Sub::Replace;
91             #pod
92             #pod my $_OLD_SUBS;
93             #pod BEGIN {
94             #pod require Foo;
95             #pod $_OLD_SUBS = Sub::Replace::sub_replace('foo' => \&Foo::foo);
96             #pod }
97             #pod
98             #pod UNITCHECK {
99             #pod Sub::Replace::sub_replace($_OLD_SUBS);
100             #pod }
101             #pod
102             #pod That means:
103             #pod
104             #pod =over 4
105             #pod
106             #pod =item *
107             #pod
108             #pod Imported subroutines are installed into the caller namespace at compile time.
109             #pod
110             #pod =item *
111             #pod
112             #pod Imported subroutines are cleaned up just after the unit which defined
113             #pod them has been compiled.
114             #pod
115             #pod =back
116             #pod
117             #pod See L<< perlsub /BEGIN, UNITCHECK, CHECK, INIT and END >> for
118             #pod the concept of "compilation unit" which is relevant here.
119             #pod
120             #pod See L for a few gotchas about why this is not simply done
121             #pod with Perl statements such as
122             #pod
123             #pod *foo = \&Foo::foo;
124             #pod
125             #pod =head1 DEBUGGING
126             #pod
127             #pod You can set the C environment variable
128             #pod for get some diagnostics information printed to C.
129             #pod
130             #pod IMPORTER_ZIM_DEBUG=1
131             #pod
132             #pod =head1 SEE ALSO
133             #pod
134             #pod L
135             #pod
136             #pod L<< perlsub /BEGIN, UNITCHECK, CHECK, INIT and END >>
137             #pod
138             #pod L
139             #pod
140             #pod L
141             #pod
142             #pod =cut
143              
144             __END__