implement passing certain import args to init_meta
[gitmo/Moose.git] / lib / Moose / Exporter.pm
CommitLineData
e606ae5f 1package Moose::Exporter;
2
3use strict;
4use warnings;
5
72643035 6our $VERSION = '1.08';
79dad293 7our $XS_VERSION = $VERSION;
ae18d5ec 8$VERSION = eval $VERSION;
9our $AUTHORITY = 'cpan:STEVAN';
10
e606ae5f 11use Class::MOP;
12use List::MoreUtils qw( first_index uniq );
13use Moose::Util::MetaRole;
091ac4b7 14use Sub::Exporter 0.980;
9f2230e9 15use Sub::Name qw(subname);
e606ae5f 16
8fa582b1 17use XSLoader;
18
79dad293 19XSLoader::load( 'Moose', $XS_VERSION );
8fa582b1 20
e606ae5f 21my %EXPORT_SPEC;
22
23sub setup_import_methods {
24 my ( $class, %args ) = @_;
25
26 my $exporting_package = $args{exporting_package} ||= caller();
27
95056a1e 28 $class->build_import_methods(
29 %args,
30 install => [qw(import unimport init_meta)]
31 );
e606ae5f 32}
33
34sub build_import_methods {
35 my ( $class, %args ) = @_;
36
37 my $exporting_package = $args{exporting_package} ||= caller();
38
39 $EXPORT_SPEC{$exporting_package} = \%args;
40
8fa582b1 41 my @exports_from = $class->_follow_also($exporting_package);
e606ae5f 42
43 my $export_recorder = {};
8fa582b1 44 my $is_reexport = {};
e606ae5f 45
e0d3eb10 46 my $exports = $class->_make_sub_exporter_params(
8fa582b1 47 [ @exports_from, $exporting_package ],
48 $export_recorder,
49 $is_reexport,
e0d3eb10 50 );
e606ae5f 51
52 my $exporter = Sub::Exporter::build_exporter(
53 {
54 exports => $exports,
0661fc1a 55 groups => { default => [':all'] }
e606ae5f 56 }
57 );
58
95056a1e 59 my %methods;
8fa582b1 60 $methods{import} = $class->_make_import_sub(
61 $exporting_package,
62 $exporter,
63 \@exports_from,
6e36501c 64 $is_reexport,
65 ($args{init_meta_params} || []),
8fa582b1 66 );
e606ae5f 67
8fa582b1 68 $methods{unimport} = $class->_make_unimport_sub(
69 $exporting_package,
70 $exports,
71 $export_recorder,
72 $is_reexport
73 );
95056a1e 74
8fa582b1 75 $methods{init_meta} = $class->_make_init_meta(
76 $exporting_package,
77 \%args
78 );
95056a1e 79
80 my $package = Class::MOP::Package->initialize($exporting_package);
906eabcd 81 for my $to_install ( @{ $args{install} || [] } ) {
95056a1e 82 my $symbol = '&' . $to_install;
906eabcd 83 next
84 unless $methods{$to_install}
85 && !$package->has_package_symbol($symbol);
86 $package->add_package_symbol( $symbol, $methods{$to_install} );
95056a1e 87 }
e606ae5f 88
8fa582b1 89 return ( $methods{import}, $methods{unimport}, $methods{init_meta} );
e606ae5f 90}
91
92{
93 my $seen = {};
94
95 sub _follow_also {
96 my $class = shift;
97 my $exporting_package = shift;
98
99 local %$seen = ( $exporting_package => 1 );
100
101 return uniq( _follow_also_real($exporting_package) );
102 }
103
104 sub _follow_also_real {
105 my $exporting_package = shift;
106
8fa582b1 107 if ( !exists $EXPORT_SPEC{$exporting_package} ) {
ba1a3c2f 108 my $loaded = Class::MOP::is_class_loaded($exporting_package);
109
110 die "Package in also ($exporting_package) does not seem to "
8fa582b1 111 . "use Moose::Exporter"
112 . ( $loaded ? "" : " (is it loaded?)" );
ba1a3c2f 113 }
e606ae5f 114
115 my $also = $EXPORT_SPEC{$exporting_package}{also};
116
117 return unless defined $also;
118
119 my @also = ref $also ? @{$also} : $also;
120
8fa582b1 121 for my $package (@also) {
122 die
123 "Circular reference in 'also' parameter to Moose::Exporter between $exporting_package and $package"
e606ae5f 124 if $seen->{$package};
125
126 $seen->{$package} = 1;
127 }
128
129 return @also, map { _follow_also_real($_) } @also;
130 }
131}
132
133sub _make_sub_exporter_params {
8fa582b1 134 my $class = shift;
135 my $packages = shift;
136 my $export_recorder = shift;
137 my $is_reexport = shift;
e606ae5f 138
139 my %exports;
140
141 for my $package ( @{$packages} ) {
142 my $args = $EXPORT_SPEC{$package}
143 or die "The $package package does not use Moose::Exporter\n";
144
5ac14e89 145 for my $name ( @{ $args->{with_meta} } ) {
0dd4228e 146 my $sub = $class->_sub_from_package( $package, $name )
147 or next;
e6a5040f 148
e606ae5f 149 my $fq_name = $package . '::' . $name;
150
5ac14e89 151 $exports{$name} = $class->_make_wrapped_sub_with_meta(
e606ae5f 152 $fq_name,
153 $sub,
154 $export_recorder,
155 );
156 }
157
5ac14e89 158 for my $name ( @{ $args->{with_caller} } ) {
0dd4228e 159 my $sub = $class->_sub_from_package( $package, $name )
160 or next;
e6a5040f 161
45975bce 162 my $fq_name = $package . '::' . $name;
163
5ac14e89 164 $exports{$name} = $class->_make_wrapped_sub(
45975bce 165 $fq_name,
166 $sub,
167 $export_recorder,
168 );
45975bce 169 }
170
e606ae5f 171 for my $name ( @{ $args->{as_is} } ) {
8fa582b1 172 my ( $sub, $coderef_name );
e606ae5f 173
174 if ( ref $name ) {
e0d3eb10 175 $sub = $name;
e05fb8ae 176
e05fb8ae 177 my $coderef_pkg;
e6a5040f 178 ( $coderef_pkg, $coderef_name )
179 = Class::MOP::get_code_info($name);
e05fb8ae 180
e0d3eb10 181 if ( $coderef_pkg ne $package ) {
8fa582b1 182 $is_reexport->{$coderef_name} = 1;
e0d3eb10 183 }
e606ae5f 184 }
185 else {
0dd4228e 186 $sub = $class->_sub_from_package( $package, $name )
187 or next;
e6a5040f 188
e6a5040f 189 $coderef_name = $name;
e606ae5f 190 }
191
192 $export_recorder->{$sub} = 1;
193
8fa582b1 194 $exports{$coderef_name} = sub {$sub};
e606ae5f 195 }
196 }
197
e0d3eb10 198 return \%exports;
e606ae5f 199}
200
0dd4228e 201sub _sub_from_package {
8fa582b1 202 my $sclass = shift;
0dd4228e 203 my $package = shift;
8fa582b1 204 my $name = shift;
0dd4228e 205
206 my $sub = do {
207 no strict 'refs';
208 \&{ $package . '::' . $name };
209 };
210
211 return $sub if defined &$sub;
212
8fa582b1 213 Carp::cluck "Trying to export undefined sub ${package}::${name}";
0dd4228e 214
215 return;
216}
217
96bb13ea 218our $CALLER;
219
220sub _make_wrapped_sub {
b4f00a34 221 my $self = shift;
96bb13ea 222 my $fq_name = shift;
223 my $sub = shift;
224 my $export_recorder = shift;
225
226 # We need to set the package at import time, so that when
227 # package Foo imports has(), we capture "Foo" as the
228 # package. This lets other packages call Foo::has() and get
229 # the right package. This is done for backwards compatibility
230 # with existing production code, not because this is a good
231 # idea ;)
232 return sub {
233 my $caller = $CALLER;
234
8fa582b1 235 my $wrapper = $self->_curry_wrapper( $sub, $fq_name, $caller );
b4f00a34 236
8fa582b1 237 my $sub = subname( $fq_name => $wrapper );
96bb13ea 238
239 $export_recorder->{$sub} = 1;
240
241 return $sub;
242 };
243}
e606ae5f 244
45975bce 245sub _make_wrapped_sub_with_meta {
246 my $self = shift;
247 my $fq_name = shift;
248 my $sub = shift;
249 my $export_recorder = shift;
250
251 return sub {
252 my $caller = $CALLER;
253
8fa582b1 254 my $wrapper = $self->_late_curry_wrapper(
255 $sub, $fq_name,
256 sub { Class::MOP::class_of(shift) } => $caller
257 );
45975bce 258
8fa582b1 259 my $sub = subname( $fq_name => $wrapper );
45975bce 260
261 $export_recorder->{$sub} = 1;
262
263 return $sub;
264 };
265}
266
6de00734 267sub _curry_wrapper {
badbc528 268 my $class = shift;
b4f00a34 269 my $sub = shift;
270 my $fq_name = shift;
6de00734 271 my @extra = @_;
b4f00a34 272
8fa582b1 273 my $wrapper = sub { $sub->( @extra, @_ ) };
274 if ( my $proto = prototype $sub ) {
275
2d7e979b 276 # XXX - Perl's prototype sucks. Use & to make set_prototype
6de00734 277 # ignore the fact that we're passing "private variables"
8fa582b1 278 &Scalar::Util::set_prototype( $wrapper, $proto );
badbc528 279 }
280 return $wrapper;
b4f00a34 281}
282
45975bce 283sub _late_curry_wrapper {
284 my $class = shift;
285 my $sub = shift;
286 my $fq_name = shift;
287 my $extra = shift;
288 my @ex_args = @_;
289
290 my $wrapper = sub {
8fa582b1 291
45975bce 292 # resolve curried arguments at runtime via this closure
8fa582b1 293 my @curry = ( $extra->(@ex_args) );
294 return $sub->( @curry, @_ );
45975bce 295 };
296
8fa582b1 297 if ( my $proto = prototype $sub ) {
298
45975bce 299 # XXX - Perl's prototype sucks. Use & to make set_prototype
300 # ignore the fact that we're passing "private variables"
8fa582b1 301 &Scalar::Util::set_prototype( $wrapper, $proto );
45975bce 302 }
303 return $wrapper;
304}
305
96bb13ea 306sub _make_import_sub {
307 shift;
308 my $exporting_package = shift;
309 my $exporter = shift;
310 my $exports_from = shift;
8fa582b1 311 my $is_reexport = shift;
6e36501c 312 my $init_meta_params = shift;
96bb13ea 313
314 return sub {
315
316 # I think we could use Sub::Exporter's collector feature
317 # to do this, but that would be rather gross, since that
318 # feature isn't really designed to return a value to the
319 # caller of the exporter sub.
320 #
321 # Also, this makes sure we preserve backwards compat for
322 # _get_caller, so it always sees the arguments in the
323 # expected order.
324 my $traits;
325 ( $traits, @_ ) = _strip_traits(@_);
326
8f30b86e 327 my $metaclass;
328 ( $metaclass, @_ ) = _strip_metaclass(@_);
8fa582b1 329 $metaclass
330 = Moose::Util::resolve_metaclass_alias( 'Class' => $metaclass )
331 if defined $metaclass && length $metaclass;
8f30b86e 332
96bb13ea 333 # Normally we could look at $_[0], but in some weird cases
334 # (involving goto &Moose::import), $_[0] ends as something
335 # else (like Squirrel).
336 my $class = $exporting_package;
337
338 $CALLER = _get_caller(@_);
339
340 # this works because both pragmas set $^H (see perldoc
341 # perlvar) which affects the current compilation -
342 # i.e. the file who use'd us - which is why we don't need
343 # to do anything special to make it affect that file
344 # rather than this one (which is already compiled)
345
346 strict->import;
347 warnings->import;
348
6e36501c 349 my %extra_args;
350 # don't want to just force @_ into a hash, since it really actually is
351 # an array
352 for my $i (1..$#_) {
353 if (grep { $_ eq $_[$i] } @$init_meta_params) {
354 $extra_args{$_[$i]} = $_[$i + 1];
355 splice @_, $i, 2;
356 }
357 }
358
96bb13ea 359 my $did_init_meta;
360 for my $c ( grep { $_->can('init_meta') } $class, @{$exports_from} ) {
8fa582b1 361
816208bc 362 # init_meta can apply a role, which when loaded uses
363 # Moose::Exporter, which in turn sets $CALLER, so we need
364 # to protect against that.
fdeb8354 365 local $CALLER = $CALLER;
6e36501c 366 $c->init_meta(
367 %extra_args,
368 for_class => $CALLER,
369 metaclass => $metaclass,
370 );
96bb13ea 371 $did_init_meta = 1;
372 }
e606ae5f 373
96bb13ea 374 if ( $did_init_meta && @{$traits} ) {
8fa582b1 375
96bb13ea 376 # The traits will use Moose::Role, which in turn uses
377 # Moose::Exporter, which in turn sets $CALLER, so we need
378 # to protect against that.
379 local $CALLER = $CALLER;
380 _apply_meta_traits( $CALLER, $traits );
381 }
382 elsif ( @{$traits} ) {
70ea9161 383 require Moose;
96bb13ea 384 Moose->throw_error(
385 "Cannot provide traits when $class does not have an init_meta() method"
386 );
387 }
e606ae5f 388
8fa582b1 389 my ( undef, @args ) = @_;
390 my $extra = shift @args if ref $args[0] eq 'HASH';
391
392 $extra ||= {};
393 if ( !$extra->{into} ) {
394 $extra->{into_level} ||= 0;
395 $extra->{into_level}++;
396 }
397
398 $class->$exporter( $extra, @args );
399
400 for my $name ( keys %{$is_reexport} ) {
401 no strict 'refs';
402 no warnings 'once';
403 _flag_as_reexport( \*{ join q{::}, $CALLER, $name } );
404 }
96bb13ea 405 };
e606ae5f 406}
407
408sub _strip_traits {
409 my $idx = first_index { $_ eq '-traits' } @_;
410
411 return ( [], @_ ) unless $idx >= 0 && $#_ >= $idx + 1;
412
413 my $traits = $_[ $idx + 1 ];
414
415 splice @_, $idx, 2;
416
8fa582b1 417 $traits = [$traits] unless ref $traits;
e606ae5f 418
419 return ( $traits, @_ );
420}
421
8f30b86e 422sub _strip_metaclass {
423 my $idx = first_index { $_ eq '-metaclass' } @_;
424
425 return ( undef, @_ ) unless $idx >= 0 && $#_ >= $idx + 1;
426
427 my $metaclass = $_[ $idx + 1 ];
428
429 splice @_, $idx, 2;
430
431 return ( $metaclass, @_ );
432}
433
e606ae5f 434sub _apply_meta_traits {
435 my ( $class, $traits ) = @_;
436
437 return unless @{$traits};
438
2571a16d 439 my $meta = Class::MOP::class_of($class);
e606ae5f 440
441 my $type = ( split /::/, ref $meta )[-1]
c245d69b 442 or Moose->throw_error(
e606ae5f 443 'Cannot determine metaclass type for trait application . Meta isa '
8fa582b1 444 . ref $meta );
e606ae5f 445
8fa582b1 446 my @resolved_traits = map {
447 ref $_
448 ? $_
449 : Moose::Util::resolve_metatrait_alias( $type => $_ )
450 } @$traits;
e606ae5f 451
452 return unless @resolved_traits;
453
f785aad8 454 my %args = ( for => $class );
455
456 if ( $meta->isa('Moose::Meta::Role') ) {
457 $args{role_metaroles} = { role => \@resolved_traits };
458 }
459 else {
460 $args{class_metaroles} = { class => \@resolved_traits };
461 }
462
463 Moose::Util::MetaRole::apply_metaroles(%args);
e606ae5f 464}
465
466sub _get_caller {
8fa582b1 467
e606ae5f 468 # 1 extra level because it's called by import so there's a layer
469 # of indirection
470 my $offset = 1;
471
472 return
473 ( ref $_[1] && defined $_[1]->{into} ) ? $_[1]->{into}
474 : ( ref $_[1] && defined $_[1]->{into_level} )
475 ? caller( $offset + $_[1]->{into_level} )
476 : caller($offset);
477}
478
479sub _make_unimport_sub {
480 shift;
481 my $exporting_package = shift;
482 my $exports = shift;
483 my $export_recorder = shift;
8fa582b1 484 my $is_reexport = shift;
e606ae5f 485
486 return sub {
487 my $caller = scalar caller();
488 Moose::Exporter->_remove_keywords(
489 $caller,
490 [ keys %{$exports} ],
491 $export_recorder,
8fa582b1 492 $is_reexport,
e606ae5f 493 );
494 };
495}
496
497sub _remove_keywords {
498 shift;
499 my $package = shift;
500 my $keywords = shift;
501 my $recorded_exports = shift;
8fa582b1 502 my $is_reexport = shift;
e606ae5f 503
504 no strict 'refs';
505
8fa582b1 506 foreach my $name ( @{$keywords} ) {
e606ae5f 507 if ( defined &{ $package . '::' . $name } ) {
508 my $sub = \&{ $package . '::' . $name };
509
510 # make sure it is from us
511 next unless $recorded_exports->{$sub};
512
8fa582b1 513 if ( $is_reexport->{$name} ) {
514 no strict 'refs';
515 next
516 unless _export_is_flagged(
517 \*{ join q{::} => $package, $name } );
518 }
519
e606ae5f 520 # and if it is from us, then undef the slot
521 delete ${ $package . '::' }{$name};
522 }
523 }
524}
525
95056a1e 526sub _make_init_meta {
527 shift;
906eabcd 528 my $class = shift;
529 my $args = shift;
95056a1e 530
f785aad8 531 my %old_style_roles;
906eabcd 532 for my $role (
533 map {"${_}_roles"}
f785aad8 534 qw(
535 metaclass
906eabcd 536 attribute_metaclass
537 method_metaclass
538 wrapped_method_metaclass
539 instance_metaclass
540 constructor_class
541 destructor_class
542 error_class
f785aad8 543 )
906eabcd 544 ) {
f785aad8 545 $old_style_roles{$role} = $args->{$role}
546 if exists $args->{$role};
95056a1e 547 }
548
549 my %base_class_roles;
906eabcd 550 %base_class_roles = ( roles => $args->{base_class_roles} )
95056a1e 551 if exists $args->{base_class_roles};
552
f785aad8 553 my %new_style_roles = map { $_ => $args->{$_} }
554 grep { exists $args->{$_} } qw( class_metaroles role_metaroles );
555
556 return unless %new_style_roles || %old_style_roles || %base_class_roles;
95056a1e 557
558 return sub {
559 shift;
560 my %options = @_;
906eabcd 561
562 return unless Class::MOP::class_of( $options{for_class} );
563
f785aad8 564 Moose::Util::MetaRole::apply_metaroles(
565 for => $options{for_class},
566 %new_style_roles,
567 %old_style_roles,
95056a1e 568 );
906eabcd 569
95056a1e 570 Moose::Util::MetaRole::apply_base_class_roles(
571 for_class => $options{for_class},
572 %base_class_roles,
906eabcd 573 )
574 if Class::MOP::class_of( $options{for_class} )
575 ->isa('Moose::Meta::Class');
576
577 return Class::MOP::class_of( $options{for_class} );
95056a1e 578 };
579}
580
e2fa092d 581sub import {
582 strict->import;
583 warnings->import;
584}
585
e606ae5f 5861;
587
588__END__
589
590=head1 NAME
591
592Moose::Exporter - make an import() and unimport() just like Moose.pm
593
594=head1 SYNOPSIS
595
596 package MyApp::Moose;
597
e606ae5f 598 use Moose ();
599 use Moose::Exporter;
600
601 Moose::Exporter->setup_import_methods(
5ac14e89 602 with_meta => [ 'has_rw', 'sugar2' ],
603 as_is => [ 'sugar3', \&Some::Random::thing ],
604 also => 'Moose',
e606ae5f 605 );
606
82ad7804 607 sub has_rw {
5ac14e89 608 my ( $meta, $name, %options ) = @_;
609 $meta->add_attribute(
610 $name,
82ad7804 611 is => 'rw',
612 %options,
613 );
614 }
615
e606ae5f 616 # then later ...
617 package MyApp::User;
618
619 use MyApp::Moose;
620
621 has 'name';
6daad0b9 622 has_rw 'size';
e606ae5f 623 thing;
624
625 no MyApp::Moose;
626
627=head1 DESCRIPTION
628
fd7ab111 629This module encapsulates the exporting of sugar functions in a
95056a1e 630C<Moose.pm>-like manner. It does this by building custom C<import>,
37e4fe95 631C<unimport>, and C<init_meta> methods for your module, based on a spec you
632provide.
e606ae5f 633
37e4fe95 634It also lets you "stack" Moose-alike modules so you can export Moose's sugar
635as well as your own, along with sugar from any random C<MooseX> module, as
636long as they all use C<Moose::Exporter>. This feature exists to let you bundle
637a set of MooseX modules into a policy module that developers can use directly
638instead of using Moose itself.
e606ae5f 639
10e0127a 640To simplify writing exporter modules, C<Moose::Exporter> also imports
641C<strict> and C<warnings> into your exporter module, as well as into
642modules that use it.
643
e606ae5f 644=head1 METHODS
645
646This module provides two public methods:
647
4b68e0de 648=over 4
649
650=item B<< Moose::Exporter->setup_import_methods(...) >>
e606ae5f 651
95056a1e 652When you call this method, C<Moose::Exporter> builds custom C<import>,
37e4fe95 653C<unimport>, and C<init_meta> methods for your module. The C<import> method
654will export the functions you specify, and can also re-export functions
655exported by some other module (like C<Moose.pm>).
e606ae5f 656
37e4fe95 657The C<unimport> method cleans the caller's namespace of all the exported
cee38bb4 658functions. This includes any functions you re-export from other
659packages. However, if the consumer of your package also imports those
660functions from the original package, they will I<not> be cleaned.
e606ae5f 661
37e4fe95 662If you pass any parameters for L<Moose::Util::MetaRole>, this method will
663generate an C<init_meta> for you as well (see below for details). This
664C<init_meta> will call C<Moose::Util::MetaRole::apply_metaclass_roles> and
665C<Moose::Util::MetaRole::apply_base_class_roles> as needed.
95056a1e 666
667Note that if any of these methods already exist, they will not be
668overridden, you will have to use C<build_import_methods> to get the
669coderef that would be installed.
e606ae5f 670
671This method accepts the following parameters:
672
4b68e0de 673=over 8
e606ae5f 674
5ac14e89 675=item * with_meta => [ ... ]
e606ae5f 676
37e4fe95 677This list of function I<names only> will be wrapped and then exported. The
5ac14e89 678wrapper will pass the metaclass object for the caller as its first argument.
679
680Many sugar functions will need to use this metaclass object to do something to
681the calling package.
e606ae5f 682
683=item * as_is => [ ... ]
684
37e4fe95 685This list of function names or sub references will be exported as-is. You can
686identify a subroutine by reference, which is handy to re-export some other
687module's functions directly by reference (C<\&Some::Package::function>).
e606ae5f 688
37e4fe95 689If you do export some other package's function, this function will never be
690removed by the C<unimport> method. The reason for this is we cannot know if
691the caller I<also> explicitly imported the sub themselves, and therefore wants
692to keep it.
e05fb8ae 693
e606ae5f 694=item * also => $name or \@names
695
696This is a list of modules which contain functions that the caller
697wants to export. These modules must also use C<Moose::Exporter>. The
698most common use case will be to export the functions from C<Moose.pm>.
5ac14e89 699Functions specified by C<with_meta> or C<as_is> take precedence over
ae8817b6 700functions exported by modules specified by C<also>, so that a module
701can selectively override functions exported by another module.
e606ae5f 702
703C<Moose::Exporter> also makes sure all these functions get removed
704when C<unimport> is called.
705
706=back
707
f785aad8 708You can also provide parameters for C<Moose::Util::MetaRole::apply_metaroles>
709and C<Moose::Util::MetaRole::base_class_roles>. Specifically, valid parameters
710are "class_metaroles", "role_metaroles", and "base_object_roles".
95056a1e 711
4b68e0de 712=item B<< Moose::Exporter->build_import_methods(...) >>
e606ae5f 713
95056a1e 714Returns two or three code refs, one for C<import>, one for
715C<unimport>, and optionally one for C<init_meta>, if the appropriate
716options are passed in.
717
37e4fe95 718Accepts the additional C<install> option, which accepts an arrayref of method
719names to install into your exporting package. The valid options are C<import>,
720C<unimport>, and C<init_meta>. Calling C<setup_import_methods> is equivalent
721to calling C<build_import_methods> with C<< install => [qw(import unimport
722init_meta)] >> except that it doesn't also return the methods.
e606ae5f 723
724Used by C<setup_import_methods>.
725
4b68e0de 726=back
727
e606ae5f 728=head1 IMPORTING AND init_meta
729
37e4fe95 730If you want to set an alternative base object class or metaclass class, see
731above for details on how this module can call L<Moose::Util::MetaRole> for
732you.
733
734If you want to do something that is not supported by this module, simply
735define an C<init_meta> method in your class. The C<import> method that
736C<Moose::Exporter> generates for you will call this method (if it exists). It
737will always pass the caller to this method via the C<for_class> parameter.
e606ae5f 738
739Most of the time, your C<init_meta> method will probably just call C<<
740Moose->init_meta >> to do the real work:
741
742 sub init_meta {
743 shift; # our class name
744 return Moose->init_meta( @_, metaclass => 'My::Metaclass' );
745 }
746
95056a1e 747Keep in mind that C<build_import_methods> will return an C<init_meta>
748method for you, which you can also call from within your custom
37e4fe95 749C<init_meta>:
750
751 my ( $import, $unimport, $init_meta ) =
752 Moose::Exporter->build_import_methods( ... );
753
754 sub import {
755 my $class = shift;
756
757 ...
758
759 $class->$import(...);
760
761 ...
762 }
763
764 sub unimport { goto &$unimport }
765
766 sub init_meta {
767 my $class = shift;
768
769 ...
770
771 $class->$init_meta(...);
772
773 ...
774 }
95056a1e 775
e606ae5f 776=head1 METACLASS TRAITS
777
778The C<import> method generated by C<Moose::Exporter> will allow the
779user of your module to specify metaclass traits in a C<-traits>
780parameter passed as part of the import:
781
782 use Moose -traits => 'My::Meta::Trait';
783
784 use Moose -traits => [ 'My::Meta::Trait', 'My::Other::Trait' ];
785
786These traits will be applied to the caller's metaclass
787instance. Providing traits for an exporting class that does not create
788a metaclass for the caller is an error.
789
c5fc2c21 790=head1 BUGS
791
792See L<Moose/BUGS> for details on reporting bugs.
793
e606ae5f 794=head1 AUTHOR
795
796Dave Rolsky E<lt>autarch@urth.orgE<gt>
797
798This is largely a reworking of code in Moose.pm originally written by
799Stevan Little and others.
800
801=head1 COPYRIGHT AND LICENSE
802
2840a3b2 803Copyright 2009 by Infinity Interactive, Inc.
e606ae5f 804
805L<http://www.iinteractive.com>
806
807This library is free software; you can redistribute it and/or modify
808it under the same terms as Perl itself.
809
810=cut