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