Do not recreate hash on every construction chip/fast1
Chip Salzenberg [Mon, 2 Jan 2012 07:02:28 +0000 (23:02 -0800)]
lib/MooseX/StrictConstructor/Trait/Class.pm
lib/MooseX/StrictConstructor/Trait/Method/Constructor.pm

index 707c75f..3d0f9a0 100644 (file)
@@ -6,24 +6,23 @@ use namespace::autoclean;
 
 use B ();
 
+my %pkg_attrs;
+
 around new_object => sub {
     my $orig     = shift;
     my $self     = shift;
     my $params   = @_ == 1 ? $_[0] : {@_};
     my $instance = $self->$orig(@_);
 
-    my %attrs = (
-        __INSTANCE__ => 1,
-        (
-            map { $_ => 1 }
-            grep {defined}
-            map  { $_->init_arg() } $self->get_all_attributes()
-        )
-    );
-
-    my @bad = sort grep { !$attrs{$_} } keys %$params;
+    my $attrs =
+      $pkg_attrs{ref($instance)} ||= {
+          __INSTANCE__ => 1,
+          map { $_ => 1 }
+          grep {defined}
+          map  { $_->init_arg() } $self->get_all_attributes()
+      };
 
-    if (@bad) {
+    if (my @bad = sort grep { !$attrs->{$_} } keys %$params) {
         $self->throw_error(
             "Found unknown attribute(s) init_arg passed to the constructor: @bad"
         );
@@ -45,11 +44,16 @@ around '_inline_BUILDALL' => sub {
         map  { $_->init_arg() } $self->get_all_attributes()
     );
 
+    my $MY = 'my';
+    if ($] >= 5.009004) {
+        push @source, "use feature 'state';";
+        $MY = 'state';
+    }
+
     return (
         @source,
-        'my %attrs = (' . ( join ' ', @attrs ) . ');',
-        'my @bad = sort grep { !$attrs{$_} } keys %{ $params };',
-        'if (@bad) {',
+        $MY.' $attrs = {' . ( join ' ', @attrs ) . '};',
+        'if (my @bad = sort grep { !$attrs->{$_} } keys %$params) {',
             'Moose->throw_error("Found unknown attribute(s) passed to the constructor: @bad");',
         '}',
     );
index 0ceec12..1eceed7 100644 (file)
@@ -20,12 +20,15 @@ around '_generate_BUILDALL' => sub {
         map  { $_->init_arg() } @{ $self->_attributes() }
     );
 
-    $source .= <<"EOF";
-my \%attrs = (@attrs);
-
-my \@bad = sort grep { ! \$attrs{\$_} }  keys \%{ \$params };
+    my $MY = 'my';
+    if ($] >= 5.009004) {
+        $source .= "use feature 'state';\n";
+        $MY = 'state';
+    }
 
-if (\@bad) {
+    $source .= <<"EOF";
+$MY \$attrs = { @attrs };
+if (my \@bad = sort grep { ! \$attrs->{\$_} } keys %\$params) {
     Moose->throw_error("Found unknown attribute(s) passed to the constructor: \@bad");
 }
 EOF