factor out set/stream code
Matt S Trout [Mon, 3 Feb 2014 03:12:20 +0000 (03:12 +0000)]
lib/DX/Op/MemberOf.pm
lib/DX/SetOver.pm [new file with mode: 0644]
t/basic_rule.t

index 2ff460e..3bcca39 100644 (file)
@@ -17,7 +17,7 @@ sub run {
   my ($member, $of) = @args{qw(member of)};
   die "member bound" if $member->is_bound;
   my $set = $state->facts->{$of->bound_value};
-  my $stream = DX::ArrayStream->from_array(@{$set}{sort keys %$set});
+  my $stream = $set->to_stream;
   return $state->bind_stream_then($member, $stream, $self->next);
 }
 
diff --git a/lib/DX/SetOver.pm b/lib/DX/SetOver.pm
new file mode 100644 (file)
index 0000000..88a964d
--- /dev/null
@@ -0,0 +1,24 @@
+package DX::SetOver;
+
+use DX::ArrayStream;
+use Moo;
+
+has over => (is => 'ro', required => 1);
+
+has values => (is => 'ro', default => sub { {} });
+
+sub to_stream {
+  my ($self) = @_;
+  my $values = $self->values;
+  return DX::ArrayStream->from_array(@{$values}{sort keys %$values});
+}
+
+sub with_value {
+  my ($self, $value) = @_;
+  return ref($self)->new(
+    %$self,
+    values => { %{$self->values}, $value->${\$self->over} => $value }
+  );
+}
+
+1;
index c6d6795..173b47b 100644 (file)
@@ -1,6 +1,7 @@
 use strictures 1;
 use Test::More;
 use DX::Solver;
+use DX::SetOver;
 
 my @servers = qw(
   kitty.scsys.co.uk
@@ -30,7 +31,14 @@ my %shells = (
 );
 
 my $solver = DX::Solver->new(
-  facts => { servers => \%servers, shells => \%shells }
+  facts => {
+    servers => DX::SetOver->new(
+      over => sub { $_[0]->{name} }, values => \%servers,
+    ),
+    shells => DX::SetOver->new(
+      over => sub { $_[0]->{name} }, values => \%shells,
+    ),
+  }
 );
 
 $solver->add_rule(