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