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