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