Mangle OnlyWhenBuilt funstionality into the role, going back to trivial map_attributes
t0m [Wed, 24 Jun 2009 22:16:37 +0000 (23:16 +0100)]
lib/MooseX/Storage/Engine.pm
lib/MooseX/Storage/Engine/Trait/OnlyWhenBuilt.pm

index 729f6d9..4cf43f7 100644 (file)
@@ -138,39 +138,12 @@ sub check_for_cycle_in_expansion {
 
 sub map_attributes {
     my ($self, $method_name, @args) = @_;
-    # The $self->object check is here to differentiate a ->pack from a 
-    # ->unpack; ->object is only defined for a ->pack
-    # no checks needed if this is class based (ie, restore)
-    unless( $self->object ) {
-        return map { $self->$method_name($_, @args) }
-            $self->class->meta->get_all_attributes;
-    }
-    
-    # if it's object based, it's a store -- in that case, 
-    # check thoroughly
-    my @rv;
-    my $o = $self->object;
-    for my $attr ( $o->meta->get_all_attributes ) {    
-        
+    map { 
+        $self->$method_name($_, @args) 
+    } grep {
         # Skip our special skip attribute :)
-        next if $attr->does(
-            'MooseX::Storage::Meta::Attribute::Trait::DoNotSerialize');
-
-        # If we're invoked with the 'OnlyWhenBuilt' trait, we should
-        # only serialize the attribute if it's already built. So, go ahead
-        # and check if the attribute has a predicate. If so, check if it's 
-        # set  and then go ahead and look it up.
-        if( $o->does('MooseX::Storage::Traits::OnlyWhenBuilt') and 
-            my $pred = $attr->predicate 
-        ) { 
-            next unless $self->object->$pred; 
-        }         
-        push @rv, $self->$method_name($attr, @args);
-    } 
-
-    return @rv;
+        !$_->does('MooseX::Storage::Meta::Attribute::Trait::DoNotSerialize') 
+    } ($self->object || $self->class)->meta->get_all_attributes;
 }
 
 ## ------------------------------------------------------------------
index 163be53..461c980 100644 (file)
@@ -1,7 +1,20 @@
 package MooseX::Storage::Engine::Trait::OnlyWhenBuilt;
 use Moose::Role;
 
-our $VERSION = 1;
+# we should
+# only serialize the attribute if it's already built. So, go ahead
+# and check if the attribute has a predicate. If so, check if it's 
+# set  and then go ahead and look it up.
+around 'collapse_attribute' => sub {
+    my ($orig, $self, $attr, @args) = @_;
+
+    my $pred = $attr->predicate if $attr->has_predicate;
+    if ($pred) {
+        return () unless $self->object->$pred();
+    }
+
+    return $self->$orig($attr, @args);
+};
 
 1;