bump version to 0.79
[gitmo/Moose.git] / lib / Moose / Exporter.pm
index a3295e6..de058f1 100644 (file)
@@ -3,7 +3,7 @@ package Moose::Exporter;
 use strict;
 use warnings;
 
-our $VERSION   = '0.72';
+our $VERSION   = '0.79';
 $VERSION = eval $VERSION;
 our $AUTHORITY = 'cpan:STEVAN';
 
@@ -11,7 +11,7 @@ use Class::MOP;
 use List::MoreUtils qw( first_index uniq );
 use Moose::Util::MetaRole;
 use Sub::Exporter;
-
+use Sub::Name qw(subname);
 
 my %EXPORT_SPEC;
 
@@ -156,8 +156,6 @@ sub _make_sub_exporter_params {
                 $is_removable{$name} = 1;
             }
 
-            $class->_make_prototyped_sub($sub);
-
             $export_recorder->{$sub} = 1;
 
             $exports{$name} = sub {$sub};
@@ -186,7 +184,7 @@ sub _make_wrapped_sub {
 
         my $wrapper = $self->_make_wrapper($caller, $sub, $fq_name);
 
-        my $sub = Class::MOP::subname($fq_name => $wrapper);
+        my $sub = subname($fq_name => $wrapper);
 
         $export_recorder->{$sub} = 1;
 
@@ -194,34 +192,17 @@ sub _make_wrapped_sub {
     };
 }
 
-sub _make_prototyped_sub {
-    shift;
-    my $sub = shift;
-
-    # If I use Scalar::Util::set_prototype, this will forever be bound to XS.
-    # And it's hard to use anyway (it requires a BLOCK or a sub{} declaration
-    # as its first argument)
-    if (my $proto = prototype $sub) {
-        $sub = eval "sub ($proto) { \$sub->(\@_) }";
-        Carp::confess if $@;
-    }
-    return $sub;
-}
-
 sub _make_wrapper {
     my $class   = shift;
     my $caller  = shift;
     my $sub     = shift;
     my $fq_name = shift;
 
-    # XXX optimization: since we're building a new sub anyways, we
-    # unroll _make_prototyped_sub here
-    my $wrapper;
+    my $wrapper = sub { $sub->($caller, @_) };
     if (my $proto = prototype $sub) {
-        $wrapper = eval "sub ($proto) { \$sub->(\$caller, \@_) }";
-        Carp::confess if $@;
-    } else {
-        $wrapper = sub { $sub->($caller, @_) };
+        # XXX - Perl's prototype sucks. Use & to make set_prototype
+        # ignore the fact that we're passing a "provate variable"
+        &Scalar::Util::set_prototype($wrapper, $proto);
     }
     return $wrapper;
 }
@@ -246,6 +227,9 @@ sub _make_import_sub {
         my $traits;
         ( $traits, @_ ) = _strip_traits(@_);
 
+        my $metaclass;
+        ( $metaclass, @_ ) = _strip_metaclass(@_);
+
         # Normally we could look at $_[0], but in some weird cases
         # (involving goto &Moose::import), $_[0] ends as something
         # else (like Squirrel).
@@ -275,7 +259,7 @@ sub _make_import_sub {
             # Moose::Exporter, which in turn sets $CALLER, so we need
             # to protect against that.
             local $CALLER = $CALLER;
-            $c->init_meta( for_class => $CALLER );
+            $c->init_meta( for_class => $CALLER, metaclass => $metaclass );
             $did_init_meta = 1;
         }
 
@@ -312,12 +296,24 @@ sub _strip_traits {
     return ( $traits, @_ );
 }
 
+sub _strip_metaclass {
+    my $idx = first_index { $_ eq '-metaclass' } @_;
+
+    return ( undef, @_ ) unless $idx >= 0 && $#_ >= $idx + 1;
+
+    my $metaclass = $_[ $idx + 1 ];
+
+    splice @_, $idx, 2;
+
+    return ( $metaclass, @_ );
+}
+
 sub _apply_meta_traits {
     my ( $class, $traits ) = @_;
 
     return unless @{$traits};
 
-    my $meta = $class->meta();
+    my $meta = Class::MOP::class_of($class);
 
     my $type = ( split /::/, ref $meta )[-1]
         or Moose->throw_error(
@@ -390,6 +386,11 @@ sub _remove_keywords {
     }
 }
 
+sub import {
+    strict->import;
+    warnings->import;
+}
+
 1;
 
 __END__
@@ -402,9 +403,6 @@ Moose::Exporter - make an import() and unimport() just like Moose.pm
 
   package MyApp::Moose;
 
-  use strict;
-  use warnings;
-
   use Moose ();
   use Moose::Exporter;
 
@@ -435,19 +433,25 @@ Moose::Exporter - make an import() and unimport() just like Moose.pm
 
 =head1 DESCRIPTION
 
-This module encapsulates the logic to export sugar functions like
-C<Moose.pm>. It does this by building custom C<import> and C<unimport>
-methods for your module, based on a spec your provide.
+This module encapsulates the exporting of sugar functions in a
+C<Moose.pm>-like manner. It does this by building custom C<import> and
+C<unimport> methods for your module, based on a spec you provide.
 
-It also lets your "stack" Moose-alike modules so you can export
+It also lets you "stack" Moose-alike modules so you can export
 Moose's sugar as well as your own, along with sugar from any random
 C<MooseX> module, as long as they all use C<Moose::Exporter>.
 
+To simplify writing exporter modules, C<Moose::Exporter> also imports
+C<strict> and C<warnings> into your exporter module, as well as into
+modules that use it.
+
 =head1 METHODS
 
 This module provides two public methods:
 
-=head2 Moose::Exporter->setup_import_methods(...)
+=over 4
+
+=item  B<< Moose::Exporter->setup_import_methods(...) >>
 
 When you call this method, C<Moose::Exporter> build custom C<import>
 and C<unimport> methods for your module. The import method will export
@@ -459,7 +463,7 @@ exported functions.
 
 This method accepts the following parameters:
 
-=over 4
+=over 8
 
 =item * with_caller => [ ... ]
 
@@ -494,12 +498,14 @@ when C<unimport> is called.
 
 =back
 
-=head2 Moose::Exporter->build_import_methods(...)
+=item B<< Moose::Exporter->build_import_methods(...) >>
 
 Returns two code refs, one for import and one for unimport.
 
 Used by C<setup_import_methods>.
 
+=back
+
 =head1 IMPORTING AND init_meta
 
 If you want to set an alternative base object class or metaclass