has vars => (is => 'ro', required => 1);
has constraint => (is => 'ro', required => 1);
+has _arg_map => (is => 'lazy', builder => sub {
+ my ($self) = @_;
+ my $name = 'arg0';
+ +{ map +($name++, $_), @{$self->vars} };
+});
+
sub run {
my ($self, $state) = @_;
- my @vars = map $state->scope_var($_)->bound_value, @{$self->vars};
+ ($state, my %args) = $self->_expand_args($state, %{$self->_arg_map});
+ my @vars = map $_->bound_value, @args{sort keys %args};
if ($self->constraint->(@vars)) {
return $state->then($self->next);
}
sub run {
my ($self, $state) = @_;
- my @args = map {
- if (!ref($_)) {
- $state->scope_var($_)
- } elsif (ref($_) eq 'ARRAY') {
- if ($_->[0] eq 'value') {
- +{ bound_value => $_->[1] };
- } else {
- die "Arrayref in argspec is not value";
- }
- } else {
- die "Argspec incomprehensible";
- }
- } @{$self->rule_args};
+ my @args = map $self->_expand_argspec($state, $_), @{$self->rule_args};
my @rules = @{$state->rule_set->rules->{$self->full_name}||[]};
die "No rules for ${\$self->full_name}" unless @rules;
my $var = DX::Var->new(id => 'OR')
with 'DX::Role::Op';
has member_var => (is => 'ro', required => 1);
-has coll_name => (is => 'ro', required => 1);
+has coll_var => (is => 'ro', required => 1);
sub run {
my ($self, $state) = @_;
- my $member = $state->scope_var($self->member_var);
+ ($state, my %args) = $self->_expand_args($state,
+ member => $self->member_var,
+ of => $self->coll_var
+ );
+ my ($member, $of) = @args{qw(member of)};
die "member bound" if $member->is_bound;
- my $set = $state->facts->{$self->coll_name};
+ my $set = $state->facts->{$of->bound_value};
my $stream = DX::ArrayStream->from_array(@{$set}{sort keys %$set});
return $state->bind_stream_then($member, $stream, $self->next);
}
$self->new(%$self, @but);
}
+sub _expand_args {
+ my ($self, $state, %spec) = @_;
+ my %args;
+ @args{keys %spec} = map $self->_expand_argspec($state, $_), values %spec;
+ return $state->expand_vars(%args);
+}
+
+sub _expand_argspec {
+ my ($self, $state, $spec) = @_;
+ if (!ref($spec)) {
+ $state->scope_var($spec)
+ } elsif (ref($spec) eq 'ARRAY') {
+ if ($spec->[0] eq 'value') {
+ +{ bound_value => $spec->[1] };
+ } else {
+ die "Arrayref in argspec is not value";
+ }
+ } else {
+ die "Argspec incomprehensible";
+ }
+}
+
+
1;
}
sub _expand_member_of {
- my ($self, $member_var, $coll_name) = @_;
+ my ($self, $member_var, $coll_var) = @_;
DX::Op::MemberOf->new(
member_var => $member_var,
- coll_name => $coll_name,
+ coll_var => $coll_var,
);
}
facts => { servers => \%servers, shells => \%shells }
);
-$solver->add_rule(server => [ 'S' ] => [ member_of => qw(S servers) ]);
+$solver->add_rule(
+ server => [ 'S' ] => [ member_of => S => [ value => 'servers' ] ]
+);
my $s = $solver->query([ 'S' ], [ call => server => 'S' ]);
is_deeply([ map $_->{S}{name}, $s->results ], [ sort @servers ]);
-$solver->add_rule(shell => [ 'S' ] => [ member_of => qw(S shells) ])
+$solver->add_rule(
+ shell => [ 'S' ] => [ member_of => S => [ value => 'shells' ] ])
->add_rule(name => [ qw(T N) ],
[ constrain => [ qw(T N) ],
sub { $_[0]->{name} eq $_[1] } ]