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