eval code directly instead of generating a sub
[p5sagit/Import-Into.git] / lib / Import / Into.pm
CommitLineData
2afb5246 1package Import::Into;
2
3use strict;
4use warnings FATAL => 'all';
5
35faefa4 6our $VERSION = '1.001001'; # 1.1.1
2afb5246 7
324e7017 8sub _prelude {
10074211 9 my $target = shift;
3946b321 10 my ($package, $file, $line)
11 = $target =~ /[^0-9]/ ? ($target) : caller($target + 1);
324e7017 12 qq{package $package;\n}
ac6d2081 13 . ($file ? "#line $line \"$file\"\n" : '')
10074211 14}
10074211 15
2afb5246 16sub import::into {
17 my ($class, $target, @args) = @_;
324e7017 18 eval _prelude($target) . '$class->import(@args); 1'
19 or die $@;
10074211 20}
21
22sub unimport::out_of {
23 my ($class, $target, @args) = @_;
324e7017 24 eval _prelude($target) . '$class->unimport(@args); 1'
25 or die $@;
2afb5246 26}
27
281;
29
30=head1 NAME
31
32Import::Into - import packages into other packages
33
34=head1 SYNOPSIS
35
36 package My::MultiExporter;
37
e0ff3439 38 use Import::Into;
39
2afb5246 40 use Thing1 ();
41 use Thing2 ();
42
43 sub import {
44 my $target = caller;
45 Thing1->import::into($target);
46 Thing2->import::into($target, qw(import arguments));
47 }
48
8c17b6f8 49Note: you don't need to do anything more clever than this provided you
50document that people wanting to re-export your module should also be using
51L<Import::Into>. In fact, for a single module you can simply do:
52
53 sub import {
54 ...
55 Thing1->import::into(scalar caller);
56 }
57
58Notably, this works:
59
60 use base qw(Exporter);
61
62 sub import {
63 shift->export_to_level(1);
64 Thing1->import::into(scalar caller);
65 }
66
aa5ad642 67Note 2: You do B<not> need to do anything to Thing1 to be able to call
68C<import::into> on it. This is a global method, and is callable on any
69package (and in fact on any object as well, although it's rarer that you'd
70want to do that).
71
10074211 72Finally, we also provide an C<unimport::out_of> to allow the exporting of the
73effect of C<no>:
74
c501842c 75 # unimport::out_of was added in 1.1.0 (1.001000)
10074211 76 sub unimport {
77 Moose->unimport::out_of(scalar caller); # no MyThing == no Moose
78 }
79
aa5ad642 80If how and why this all works is of interest to you, please read on to the
81description immediately below.
82
e0ff3439 83=head1 DESCRIPTION
84
85Writing exporters is a pain. Some use L<Exporter>, some use L<Sub::Exporter>,
86some use L<Moose::Exporter>, some use L<Exporter::Declare> ... and some things
87are pragmas.
88
89If you want to re-export other things, you have to know which is which.
90L<Exporter> subclasses provide export_to_level, but if they overrode their
91import method all bets are off. L<Sub::Exporter> provides an into parameter
92but figuring out something used it isn't trivial. Pragmas need to have
93their C<import> method called directly since they affect the current unit of
94compilation.
95
96It's ... annoying.
97
98However, there is an approach that actually works for all of these types.
99
100 eval "package $target; use $thing;"
101
102will work for anything checking caller, which is everything except pragmas.
103But it doesn't work for pragmas - pragmas need:
104
105 $thing->import;
106
8c17b6f8 107because they're designed to affect the code currently being compiled - so
108within an eval, that's the scope of the eval itself, not the module that
109just C<use>d you - so
110
111 sub import {
112 eval "use strict;"
113 }
114
115doesn't do what you wanted, but
116
117 sub import {
118 strict->import;
119 }
120
121will apply L<strict> to the calling file correctly.
122
123Of course, now you have two new problems - first, that you still need to
124know if something's a pragma, and second that you can't use either of
125these approaches alone on something like L<Moose> or L<Moo> that's both
126an exporter and a pragma.
127
128So, the complete solution is:
e0ff3439 129
130 my $sub = eval "package $target; sub { shift->import(\@_) }";
131 $sub->($thing, @import_args);
132
133which means that import is called from the right place for pragmas to take
8c17b6f8 134effect, and from the right package for caller checking to work - and so
135behaves correctly for all types of exporter, for pragmas, and for hybrids.
e0ff3439 136
137Remembering all this, however, is excessively irritating. So I wrote a module
aa5ad642 138so I didn't have to anymore. Loading L<Import::Into> creates a global method
139C<import::into> which you can call on any package to import it into another
e0ff3439 140package. So now you can simply write:
141
142 use Import::Into;
143
144 $thing->import::into($target, @import_args);
145
aa5ad642 146This works because of how perl resolves method calls - a call to a simple
147method name is resolved against the package of the class or object, so
148
149 $thing->method_name(@args);
150
151is roughly equivalent to:
152
153 my $code_ref = $thing->can('method_name');
154 $code_ref->($thing, @args);
155
156while if a C<::> is found, the lookup is made relative to the package name
157(i.e. everything before the last C<::>) so
158
159 $thing->Package::Name::method_name(@args);
160
161is roughly equivalent to:
162
163 my $code_ref = Package::Name->can('method_name');
164 $code_ref->($thing, @args);
165
166So since L<Import::Into> defines a method C<into> in package C<import>
167the syntax reliably calls that.
168
169For more craziness of this order, have a look at the article I wrote at
170L<http://shadow.cat/blog/matt-s-trout/madness-with-methods> which covers
171coderef abuse and the C<${\...}> syntax.
172
173Final note: You do still need to ensure that you already loaded C<$thing> - if
174you're receiving this from a parameter, I recommend using L<Module::Runtime>:
e0ff3439 175
176 use Import::Into;
177 use Module::Runtime qw(use_module);
178
179 use_module($thing)->import::into($target, @import_args);
180
181And that's it.
182
95ecfed2 183=head1 ACKNOWLEDGEMENTS
184
185Thanks to Getty for asking "how can I get C<< use strict; use warnings; >>
186turned on for all consumers of my code?" and then "why is this not a
187module?!".
188
2afb5246 189=head1 AUTHOR
190
191mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk>
192
e0ff3439 193=head1 CONTRIBUTORS
194
93bb9005 195haarg - Graham Knop (cpan:HAARG) <haarg@haarg.org>
e0ff3439 196
2afb5246 197=head1 COPYRIGHT
198
aa5ad642 199Copyright (c) 2012 the Import::Into L</AUTHOR> and L</CONTRIBUTORS>
2afb5246 200as listed above.
201
202=head1 LICENSE
203
204This library is free software and may be distributed under the same terms
205as perl itself.