use &function notation to silence Scalar::Util::set_prototype
Daisuke Maki (lestrrat) [Wed, 11 Mar 2009 03:23:51 +0000 (12:23 +0900)]
lib/Moose/Exporter.pm

index a3295e6..310dc0b 100644 (file)
@@ -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};
@@ -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;
 }