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