File Coverage

blib/lib/Importer/Zim/EndOfScope.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::EndOfScope;
3             $Importer::Zim::EndOfScope::VERSION = '0.3.0';
4             # ABSTRACT: Import functions with compilation block scope
5              
6 2     2   51941 use 5.010001;
  2         16  
7              
8             BEGIN {
9 2     2   659 require Importer::Zim::Base;
10 2         9317 Importer::Zim::Base->VERSION('0.8.0');
11 2         55 our @ISA = qw(Importer::Zim::Base);
12             }
13              
14 2     2   528 use B::Hooks::EndOfScope ();
  2         13501  
  2         35  
15 2     2   455 use Sub::Replace ();
  2         2294  
  2         47  
16              
17 2     2   12 use Importer::Zim::Utils 0.8.0 qw(DEBUG carp);
  2         28  
  2         10  
18              
19             sub import {
20 3     3   765 my $class = shift;
21              
22 3         4 carp "$class->import(@_)" if DEBUG;
23 3         13 my @exports = $class->_prepare_args(@_);
24              
25 3         640 my $caller = caller;
26 3         6 return _export_to( map { ; "${caller}::$_->{export}" => $_->{code} }
  7         20  
27             @exports );
28             }
29              
30             sub export_to {
31 0     0 0 0 my $t = shift;
32 0 0 0     0 @_ = %{ $_[0] } if @_ == 1 && ref $_[0] eq 'HASH';
  0         0  
33 0 0       0 @_ = map { $_ & 1 ? $_[$_] : "${t}::$_[$_]" } 0 .. $#_;
  0         0  
34 0         0 goto &_export_to;
35             }
36              
37             sub _export_to {
38 3     3   7 my $old = Sub::Replace::sub_replace(@_);
39              
40             # Clean it up after a scope finished compilation
41             B::Hooks::EndOfScope::on_scope_end(
42             sub {
43 3     3   206 warn qq{ Restoring @{[map qq{"$_"}, sort keys %$old]}\n}
44             if DEBUG;
45 3         7 Sub::Replace::sub_replace($old);
46             }
47 3 50       856 ) if %$old;
48             }
49              
50 2     2   619 no Importer::Zim::Utils qw(DEBUG carp);
  2         4  
  2         9  
51              
52             1;
53              
54             #pod =encoding utf8
55             #pod
56             #pod =head1 SYNOPSIS
57             #pod
58             #pod use Importer::Zim::EndOfScope 'Scalar::Util' => 'blessed';
59             #pod use Importer::Zim::EndOfScope 'Scalar::Util' =>
60             #pod ( 'blessed' => { -as => 'typeof' } );
61             #pod
62             #pod use Importer::Zim::EndOfScope 'Mango::BSON' => ':bson';
63             #pod
64             #pod use Importer::Zim::EndOfScope 'Foo' => { -version => '3.0' } => 'foo';
65             #pod
66             #pod use Importer::Zim::EndOfScope 'SpaceTime::Machine' => [qw(robot rubber_pig)];
67             #pod
68             #pod =head1 DESCRIPTION
69             #pod
70             #pod "Wait a minute! What planet is this?"
71             #pod – Zim
72             #pod
73             #pod This is a backend for L which makes
74             #pod imported symbols available during the compilation of
75             #pod the surrounding scope.
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. (This time interval should be even shorter
81             #pod than the one that applies to L.)
82             #pod
83             #pod =head1 HOW IT WORKS
84             #pod
85             #pod The statement
86             #pod
87             #pod use Importer::Zim::EndOfScope 'Foo' => 'foo';
88             #pod
89             #pod works sort of
90             #pod
91             #pod use B::Hooks::EndOfScope;
92             #pod
93             #pod my $_OLD_SUBS;
94             #pod BEGIN {
95             #pod require Foo;
96             #pod $_OLD_SUBS = Sub::Replace::sub_replace('foo' => \&Foo::foo);
97             #pod }
98             #pod
99             #pod on_scope_end {
100             #pod Sub::Replace::sub_replace($_OLD_SUBS);
101             #pod }
102             #pod
103             #pod That means:
104             #pod
105             #pod =over 4
106             #pod
107             #pod =item *
108             #pod
109             #pod Imported subroutines are installed into the caller namespace at compile time.
110             #pod
111             #pod =item *
112             #pod
113             #pod Imported subroutines are cleaned up after perl finished compiling
114             #pod the surrounding scope.
115             #pod
116             #pod =back
117             #pod
118             #pod See L for a few gotchas about why this is not simply done
119             #pod with Perl statements such as
120             #pod
121             #pod *foo = \&Foo::foo;
122             #pod
123             #pod =head1 DEBUGGING
124             #pod
125             #pod You can set the C environment variable
126             #pod for get some diagnostics information printed to C.
127             #pod
128             #pod IMPORTER_ZIM_DEBUG=1
129             #pod
130             #pod =head1 SEE ALSO
131             #pod
132             #pod L
133             #pod
134             #pod L
135             #pod
136             #pod L
137             #pod
138             #pod =cut
139              
140             __END__