3 use aliased 'DX::Op::FromCode';
4 use aliased 'DX::ArrayStream';
18 my @shells = qw(csh bash);
21 bash => { map +($_ => 1),
22 qw(joe.example.com kitty.scsys.co.uk) },
23 csh => { map +($_ => 1),
24 qw(jim.example.com joe.example.com bob.example.com) },
28 my ($var, $array) = @_;
30 my ($self, $state) = @_;
31 $state->bind_stream_then(
32 $state->scope_var($var),
33 ArrayStream->from_array(@$array),
40 my ($vars, $test) = @_;
42 my ($self, $state) = @_;
43 my @values = map $state->scope_var($_)->bound_value, @$vars;
44 if ($test->(@values)) {
45 return $state->then($self->next);
47 return $state->backtrack;
54 code => bind_array(S => \@servers),
55 next => FromCode->new(
56 code => test_values([ 'S' ], sub { $_[0] =~ /\.example\.com$/ }),
67 my %scope = map +($_ => $_), @{$vars};
68 my %by_id = map +($_ => DX::Var->new(id => $_)), @{$vars};
79 my $stream = DX::ResultStream->new(for_state => make_state([ 'S' ], $op));
81 is($stream->next->{'S'}, $_)
82 for qw(jim.example.com joe.example.com bob.example.com);
84 is($stream->next, undef, 'No more');
86 my $complex_op = FromCode->new(
87 code => bind_array(S => \@servers),
88 next => FromCode->new(
89 code => test_values([ 'S' ], sub { $_[0] =~ /\.example\.com$/ }),
90 next => FromCode->new(
91 code => bind_array(P => \@shells),
92 next => FromCode->new(
93 code => test_values([ qw(S P) ], sub { $shells{$_[1]}{$_[0]} }),
99 my $cstream = DX::ResultStream->new(
100 for_state => make_state([ qw(S P) ], $complex_op)
104 [ $cstream->results ],
106 { P => 'csh', S => 'jim.example.com' },
107 { P => 'csh', S => 'joe.example.com' },
108 { P => 'bash', S => 'joe.example.com' },
109 { P => 'csh', S => 'bob.example.com' },
114 my $pop_stack = FromCode->new(
116 my ($self, $state) = @_;
117 my @stack = @{$state->return_stack};
118 my $top = pop @stack;
119 $state->but(return_stack => \@stack, next_op => $top);
123 my $inner_op = make_op($pop_stack);
125 my $call_op = FromCode->new(
127 my ($self, $state) = @_;
128 my @rst = @{$state->return_stack};
129 my $save_scope = $state->scope;
130 my %scope = (S => $save_scope->{S});
131 my $ret_op = FromCode->new(
132 code => sub { $_[1]->but(scope => $save_scope, next_op => $_[0]->next) },
137 return_stack => [ @rst, $ret_op ],
141 next => FromCode->new(
142 code => bind_array(P => \@shells),
143 next => FromCode->new(
144 code => test_values([ qw(S P) ], sub { $shells{$_[1]}{$_[0]} }),
149 my $callstream = DX::ResultStream->new(
150 for_state => make_state([ qw(S P) ], $call_op)
154 [ $callstream->results ],
156 { P => 'csh', S => 'jim.example.com' },
157 { P => 'csh', S => 'joe.example.com' },
158 { P => 'bash', S => 'joe.example.com' },
159 { P => 'csh', S => 'bob.example.com' },
164 my $has_csh = FromCode->new(
165 code => test_values([ 'S' ], sub { $shells{csh}{$_[0]} }),
168 my $has_bash = FromCode->new(
169 code => test_values([ 'S' ], sub { $shells{bash}{$_[0]} }),
174 my ($self, $state) = @_;
175 my $var = DX::Var->new(id => 'OR')->with_stream(
176 my $stream = ArrayStream->from_array($has_csh, $has_bash)
178 my $inner_or = FromCode->new(
179 code => sub { $_[1]->then($var->bound_value) }
182 return_stack => [ @{$state->return_stack}, $self->next ],
184 )->mark_choice($var);
187 my $top_or = FromCode->new(
188 code => bind_array(S => \@servers),
189 next => FromCode->new(code => $or_code),
192 my $orstream = DX::ResultStream->new(
193 for_state => make_state([ qw(S) ], $top_or)
197 [ $orstream->results ],
200 S => "kitty.scsys.co.uk"
203 S => "jim.example.com"
206 S => "joe.example.com"
209 S => "joe.example.com"
212 S => "bob.example.com"
218 my $top_or_2 = FromCode->new(
219 code => bind_array(S => \@servers),
220 next => FromCode->new(
222 next => FromCode->new(
223 code => test_values([ 'S' ], sub { $_[0] =~ /\.example\.com$/ }),
228 my $orstream_2 = DX::ResultStream->new(
229 for_state => make_state([ qw(S) ], $top_or_2)
233 [ $orstream_2->results ],
236 S => "jim.example.com"
239 S => "joe.example.com"
242 S => "joe.example.com"
245 S => "bob.example.com"