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