1 package Moose::Exporter;
7 $VERSION = eval $VERSION;
8 our $AUTHORITY = 'cpan:STEVAN';
11 use List::MoreUtils qw( first_index uniq );
12 use Moose::Util::MetaRole;
18 sub setup_import_methods {
19 my ( $class, %args ) = @_;
21 my $exporting_package = $args{exporting_package} ||= caller();
23 my ( $import, $unimport ) = $class->build_import_methods(%args);
26 *{ $exporting_package . '::import' } = $import;
27 *{ $exporting_package . '::unimport' } = $unimport;
30 sub build_import_methods {
31 my ( $class, %args ) = @_;
33 my $exporting_package = $args{exporting_package} ||= caller();
35 $EXPORT_SPEC{$exporting_package} = \%args;
37 my @exports_from = $class->_follow_also( $exporting_package );
39 my $export_recorder = {};
41 my ( $exports, $is_removable )
42 = $class->_make_sub_exporter_params(
43 [ @exports_from, $exporting_package ], $export_recorder );
45 my $exporter = Sub::Exporter::build_exporter(
48 groups => { default => [':all'] }
52 # $args{_export_to_main} exists for backwards compat, because
53 # Moose::Util::TypeConstraints did export to main (unlike Moose &
55 my $import = $class->_make_import_sub( $exporting_package, $exporter,
56 \@exports_from, $args{_export_to_main} );
58 my $unimport = $class->_make_unimport_sub( $exporting_package, $exports,
59 $is_removable, $export_recorder );
61 return ( $import, $unimport )
69 my $exporting_package = shift;
71 local %$seen = ( $exporting_package => 1 );
73 return uniq( _follow_also_real($exporting_package) );
76 sub _follow_also_real {
77 my $exporting_package = shift;
79 die "Package in also ($exporting_package) does not seem to use Moose::Exporter"
80 unless exists $EXPORT_SPEC{$exporting_package};
82 my $also = $EXPORT_SPEC{$exporting_package}{also};
84 return unless defined $also;
86 my @also = ref $also ? @{$also} : $also;
88 for my $package (@also)
90 die "Circular reference in also parameter to Moose::Exporter between $exporting_package and $package"
93 $seen->{$package} = 1;
96 return @also, map { _follow_also_real($_) } @also;
100 sub _make_sub_exporter_params {
102 my $packages = shift;
103 my $export_recorder = shift;
108 for my $package ( @{$packages} ) {
109 my $args = $EXPORT_SPEC{$package}
110 or die "The $package package does not use Moose::Exporter\n";
112 for my $name ( @{ $args->{with_caller} } ) {
115 \&{ $package . '::' . $name };
118 my $fq_name = $package . '::' . $name;
120 $exports{$name} = $class->_make_wrapped_sub(
126 $is_removable{$name} = 1;
129 for my $name ( @{ $args->{as_is} } ) {
135 # Even though Moose re-exports things from Carp &
136 # Scalar::Util, we don't want to remove those at
137 # unimport time, because the importing package may
138 # have imported them explicitly ala
140 # use Carp qw( confess );
142 # This is a hack. Since we can't know whether they
143 # really want to keep these subs or not, we err on the
144 # safe side and leave them in.
146 ( $coderef_pkg, $name ) = Class::MOP::get_code_info($name);
148 $is_removable{$name} = $coderef_pkg eq $package ? 1 : 0;
153 \&{ $package . '::' . $name };
156 $is_removable{$name} = 1;
159 $class->_make_prototyped_sub($sub);
161 $export_recorder->{$sub} = 1;
163 $exports{$name} = sub {$sub};
167 return ( \%exports, \%is_removable );
172 sub _make_wrapped_sub {
176 my $export_recorder = shift;
178 # We need to set the package at import time, so that when
179 # package Foo imports has(), we capture "Foo" as the
180 # package. This lets other packages call Foo::has() and get
181 # the right package. This is done for backwards compatibility
182 # with existing production code, not because this is a good
185 my $caller = $CALLER;
187 my $wrapper = $self->_make_wrapper($caller, $sub, $fq_name);
189 my $sub = Class::MOP::subname($fq_name => $wrapper);
191 $export_recorder->{$sub} = 1;
197 sub _make_prototyped_sub {
201 # If I use Scalar::Util::set_prototype, this will forever be bound to XS.
202 # And it's hard to use anyway (it requires a BLOCK or a sub{} declaration
203 # as its first argument)
204 if (my $proto = prototype $sub) {
205 $sub = eval "sub ($proto) { \$sub->(\@_) }";
217 # XXX optimization: since we're building a new sub anyways, we
218 # unroll _make_prototyped_sub here
220 if (my $proto = prototype $sub) {
221 $wrapper = eval "sub ($proto) { \$sub->(\$caller, \@_) }";
224 $wrapper = sub { $sub->($caller, @_) };
229 sub _make_import_sub {
231 my $exporting_package = shift;
232 my $exporter = shift;
233 my $exports_from = shift;
234 my $export_to_main = shift;
238 # I think we could use Sub::Exporter's collector feature
239 # to do this, but that would be rather gross, since that
240 # feature isn't really designed to return a value to the
241 # caller of the exporter sub.
243 # Also, this makes sure we preserve backwards compat for
244 # _get_caller, so it always sees the arguments in the
247 ( $traits, @_ ) = _strip_traits(@_);
249 # Normally we could look at $_[0], but in some weird cases
250 # (involving goto &Moose::import), $_[0] ends as something
251 # else (like Squirrel).
252 my $class = $exporting_package;
254 $CALLER = _get_caller(@_);
256 # this works because both pragmas set $^H (see perldoc
257 # perlvar) which affects the current compilation -
258 # i.e. the file who use'd us - which is why we don't need
259 # to do anything special to make it affect that file
260 # rather than this one (which is already compiled)
265 # we should never export to main
266 if ( $CALLER eq 'main' && !$export_to_main ) {
268 qq{$class does not export its sugar to the 'main' package.\n};
273 for my $c ( grep { $_->can('init_meta') } $class, @{$exports_from} ) {
274 # init_meta can apply a role, which when loaded uses
275 # Moose::Exporter, which in turn sets $CALLER, so we need
276 # to protect against that.
277 local $CALLER = $CALLER;
278 $c->init_meta( for_class => $CALLER );
282 if ( $did_init_meta && @{$traits} ) {
283 # The traits will use Moose::Role, which in turn uses
284 # Moose::Exporter, which in turn sets $CALLER, so we need
285 # to protect against that.
286 local $CALLER = $CALLER;
287 _apply_meta_traits( $CALLER, $traits );
289 elsif ( @{$traits} ) {
292 "Cannot provide traits when $class does not have an init_meta() method"
302 my $idx = first_index { $_ eq '-traits' } @_;
304 return ( [], @_ ) unless $idx >= 0 && $#_ >= $idx + 1;
306 my $traits = $_[ $idx + 1 ];
310 $traits = [ $traits ] unless ref $traits;
312 return ( $traits, @_ );
315 sub _apply_meta_traits {
316 my ( $class, $traits ) = @_;
318 return unless @{$traits};
320 my $meta = $class->meta();
322 my $type = ( split /::/, ref $meta )[-1]
323 or Moose->throw_error(
324 'Cannot determine metaclass type for trait application . Meta isa '
328 = map { Moose::Util::resolve_metatrait_alias( $type => $_ ) }
331 return unless @resolved_traits;
333 Moose::Util::MetaRole::apply_metaclass_roles(
335 metaclass_roles => \@resolved_traits,
340 # 1 extra level because it's called by import so there's a layer
345 ( ref $_[1] && defined $_[1]->{into} ) ? $_[1]->{into}
346 : ( ref $_[1] && defined $_[1]->{into_level} )
347 ? caller( $offset + $_[1]->{into_level} )
351 sub _make_unimport_sub {
353 my $exporting_package = shift;
355 my $is_removable = shift;
356 my $export_recorder = shift;
359 my $caller = scalar caller();
360 Moose::Exporter->_remove_keywords(
362 [ keys %{$exports} ],
369 sub _remove_keywords {
372 my $keywords = shift;
373 my $is_removable = shift;
374 my $recorded_exports = shift;
378 foreach my $name ( @{ $keywords } ) {
379 next unless $is_removable->{$name};
381 if ( defined &{ $package . '::' . $name } ) {
382 my $sub = \&{ $package . '::' . $name };
384 # make sure it is from us
385 next unless $recorded_exports->{$sub};
387 # and if it is from us, then undef the slot
388 delete ${ $package . '::' }{$name};
399 Moose::Exporter - make an import() and unimport() just like Moose.pm
403 package MyApp::Moose;
411 Moose::Exporter->setup_import_methods(
412 with_caller => [ 'has_rw', 'sugar2' ],
413 as_is => [ 'sugar3', \&Some::Random::thing ],
418 my ($caller, $name, %options) = @_;
419 Class::MOP::Class->initialize($caller)->add_attribute($name,
438 This module encapsulates the logic to export sugar functions like
439 C<Moose.pm>. It does this by building custom C<import> and C<unimport>
440 methods for your module, based on a spec your provide.
442 It also lets your "stack" Moose-alike modules so you can export
443 Moose's sugar as well as your own, along with sugar from any random
444 C<MooseX> module, as long as they all use C<Moose::Exporter>.
448 This module provides two public methods:
450 =head2 Moose::Exporter->setup_import_methods(...)
452 When you call this method, C<Moose::Exporter> build custom C<import>
453 and C<unimport> methods for your module. The import method will export
454 the functions you specify, and you can also tell it to export
455 functions exported by some other module (like C<Moose.pm>).
457 The C<unimport> method cleans the callers namespace of all the
460 This method accepts the following parameters:
464 =item * with_caller => [ ... ]
466 This a list of function I<names only> to be exported wrapped and then
467 exported. The wrapper will pass the name of the calling package as the
468 first argument to the function. Many sugar functions need to know
469 their caller so they can get the calling package's metaclass object.
471 =item * as_is => [ ... ]
473 This a list of function names or sub references to be exported
474 as-is. You can identify a subroutine by reference, which is handy to
475 re-export some other module's functions directly by reference
476 (C<\&Some::Package::function>).
478 If you do export some other packages function, this function will
479 never be removed by the C<unimport> method. The reason for this is we
480 cannot know if the caller I<also> explicitly imported the sub
481 themselves, and therefore wants to keep it.
483 =item * also => $name or \@names
485 This is a list of modules which contain functions that the caller
486 wants to export. These modules must also use C<Moose::Exporter>. The
487 most common use case will be to export the functions from C<Moose.pm>.
488 Functions specified by C<with_caller> or C<as_is> take precedence over
489 functions exported by modules specified by C<also>, so that a module
490 can selectively override functions exported by another module.
492 C<Moose::Exporter> also makes sure all these functions get removed
493 when C<unimport> is called.
497 =head2 Moose::Exporter->build_import_methods(...)
499 Returns two code refs, one for import and one for unimport.
501 Used by C<setup_import_methods>.
503 =head1 IMPORTING AND init_meta
505 If you want to set an alternative base object class or metaclass
506 class, simply define an C<init_meta> method in your class. The
507 C<import> method that C<Moose::Exporter> generates for you will call
508 this method (if it exists). It will always pass the caller to this
509 method via the C<for_class> parameter.
511 Most of the time, your C<init_meta> method will probably just call C<<
512 Moose->init_meta >> to do the real work:
515 shift; # our class name
516 return Moose->init_meta( @_, metaclass => 'My::Metaclass' );
519 =head1 METACLASS TRAITS
521 The C<import> method generated by C<Moose::Exporter> will allow the
522 user of your module to specify metaclass traits in a C<-traits>
523 parameter passed as part of the import:
525 use Moose -traits => 'My::Meta::Trait';
527 use Moose -traits => [ 'My::Meta::Trait', 'My::Other::Trait' ];
529 These traits will be applied to the caller's metaclass
530 instance. Providing traits for an exporting class that does not create
531 a metaclass for the caller is an error.
535 Dave Rolsky E<lt>autarch@urth.orgE<gt>
537 This is largely a reworking of code in Moose.pm originally written by
538 Stevan Little and others.
540 =head1 COPYRIGHT AND LICENSE
542 Copyright 2009 by Infinity Interactive, Inc.
544 L<http://www.iinteractive.com>
546 This library is free software; you can redistribute it and/or modify
547 it under the same terms as Perl itself.