Do not recreate hash on every construction
[gitmo/MooseX-StrictConstructor.git] / lib / MooseX / StrictConstructor / Trait / Class.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");',
         '}',
     );