1 package Moose::Exporter;
7 use List::MoreUtils qw( uniq );
13 sub build_import_methods {
17 my $exporting_package = caller();
19 $EXPORT_SPEC{$exporting_package} = \%args;
21 my @exports_from = $class->_follow_also( $exporting_package );
24 = $class->_process_exports( $exporting_package, @exports_from );
26 my $exporter = Sub::Exporter::build_exporter(
29 groups => { default => [':all'] }
33 my $import = $class->_make_import_sub( $exporter, \@exports_from );
35 my $unimport = $class->_make_unimport_sub( \@exports_from, [ keys %{$exports} ] );
38 *{ $exporting_package . '::import' } = $import;
39 *{ $exporting_package . '::unimport' } = $unimport;
47 my $exporting_package = shift;
49 %seen = ( $exporting_package => 1 );
51 return uniq( _follow_also_real($exporting_package) );
54 sub _follow_also_real {
55 my $exporting_package = shift;
57 die "Package in also ($exporting_package) does not seem to use MooseX::Exporter"
58 unless exists $EXPORT_SPEC{$exporting_package};
60 my $also = $EXPORT_SPEC{$exporting_package}{also};
62 return unless defined $also;
64 my @also = ref $also ? @{$also} : $also;
66 for my $package (@also)
68 die "Circular reference in also parameter to MooseX::Exporter between $exporting_package and $package"
74 return @also, map { _follow_also_real($_) } @also;
78 sub _process_exports {
84 for my $package (@packages) {
85 my $args = $EXPORT_SPEC{$package}
86 or die "The $package package does not use Moose::Exporter\n";
88 for my $name ( @{ $args->{with_caller} } ) {
91 \&{ $package . '::' . $name };
94 $exports{$name} = $class->_make_wrapped_sub(
101 for my $name ( @{ $args->{as_is} } ) {
106 $name = ( Class::MOP::get_code_info($name) )[1];
111 \&{ $package . '::' . $name };
115 $exports{$name} = sub {$sub};
123 # This variable gets closed over in each export _generator_. Then
124 # in the generator we grab the value and close over it _again_ in
125 # the real export, so it gets captured each time the generator
128 # In the meantime, we arrange for the import method we generate to
129 # set this variable to the caller each time it is called.
131 # This is all a bit confusing, but it works.
134 sub _make_wrapped_sub {
136 my $exporting_package = shift;
140 # We need to set the package at import time, so that when
141 # package Foo imports has(), we capture "Foo" as the
142 # package. This lets other packages call Foo::has() and get
143 # the right package. This is done for backwards compatibility
144 # with existing production code, not because this is a good
147 my $caller = $CALLER;
148 Class::MOP::subname( $exporting_package . '::'
149 . $name => sub { $sub->( $caller, @_ ) } );
153 sub _make_import_sub {
155 my $exporter = shift;
156 my $exports_from = shift;
160 # It's important to leave @_ as-is for the benefit of
164 $CALLER = Moose::Exporter::_get_caller(@_);
166 # this works because both pragmas set $^H (see perldoc
167 # perlvar) which affects the current compilation -
168 # i.e. the file who use'd us - which is why we don't need
169 # to do anything special to make it affect that file
170 # rather than this one (which is already compiled)
175 # we should never export to main
176 if ( $CALLER eq 'main' ) {
178 qq{$class does not export its sugar to the 'main' package.\n};
182 for my $c (grep { $_->can('init_meta') } $class, @{$exports_from} ) {
184 $c->init_meta( for_class => $CALLER );
193 # 1 extra level because it's called by import so there's a layer
198 ( ref $_[1] && defined $_[1]->{into} ) ? $_[1]->{into}
199 : ( ref $_[1] && defined $_[1]->{into_level} )
200 ? caller( $offset + $_[1]->{into_level} )
204 sub _make_unimport_sub {
207 my $keywords = shift;
211 my $caller = scalar caller();
212 Moose::Exporter->_remove_keywords(
214 [ $class, @{$sources} ],
220 sub _remove_keywords {
224 my $keywords = shift;
226 my %sources = map { $_ => 1 } @{$sources};
230 # loop through the keywords ...
231 foreach my $name ( @{$keywords} ) {
234 if ( defined &{ $package . '::' . $name } ) {
235 my $keyword = \&{ $package . '::' . $name };
237 # make sure it is from us
238 my ($pkg_name) = Class::MOP::get_code_info($keyword);
239 next unless $sources{$pkg_name};
241 # and if it is from us, then undef the slot
242 delete ${ $package . '::' }{$name};
253 Moose::Exporter - make an import() and unimport() just like Moose.pm
257 package MyApp::Moose;
265 Moose::Exporter->build_export_methods(
266 export => [ 'sugar1', 'sugar2', \&Some::Random::thing ],
267 init_meta_args => { metaclass_class => 'MyApp::Meta::Class' ],
276 sugar1 'do your thing';
283 This module encapsulates the logic to export sugar functions like
284 C<Moose.pm>. It does this by building custom C<import> and C<unimport>
285 methods for your module, based on a spec your provide.
287 It also lets your "stack" Moose-alike modules so you can export
288 Moose's sugar as well as your own, along with sugar from any random
289 C<MooseX> module, as long as they all use C<Moose::Exporter>.
293 This module provides exactly one public method:
295 =head2 Moose::Exporter->build_import_methods(...)
297 When you call this method, C<Moose::Exporter> build custom C<import>
298 and C<unimport> methods for your module. The import method will export
299 the functions you specify, and you can also tell it to export
300 functions exported by some other module (like C<Moose.pm>).
302 The C<unimport> method cleans the callers namespace of all the
305 This method accepts the following parameters:
309 =item * with_caller => [ ... ]
311 This a list of function I<names only> to be exported wrapped and then
312 exported. The wrapper will pass the name of the calling package as the
313 first argument to the function. Many sugar functions need to know
314 their caller so they can get the calling package's metaclass object.
316 =item * as_is => [ ... ]
318 This a list of function names or sub references to be exported
319 as-is. You can identify a subroutine by reference, which is handy to
320 re-export some other module's functions directly by reference
321 (C<\&Some::Package::function>).
323 =item * init_meta_args
331 Dave Rolsky E<lt>autarch@urth.orgE<gt>
333 This is largely a reworking of code in Moose.pm originally written by
334 Stevan Little and others.
336 =head1 COPYRIGHT AND LICENSE
338 Copyright 2008 by Infinity Interactive, Inc.
340 L<http://www.iinteractive.com>
342 This library is free software; you can redistribute it and/or modify
343 it under the same terms as Perl itself.