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