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