use VarRef for derived bindings
[scpubgit/DKit.git] / lib / DX / Op / Prop.pm
CommitLineData
896fd92e 1package DX::Op::Prop;
2
165d0b2c 3use DX::VarRef;
896fd92e 4use Moo;
5
6with 'DX::Role::Op';
7
8has of => (is => 'ro', required => 1);
9has name => (is => 'ro', required => 1);
10has value => (is => 'ro', required => 1);
11
12sub run {
13 my ($self, $state) = @_;
14 ($state, my %args) = $self->_expand_args(
15 $state, map +($_ => $self->$_), qw(of name value)
16 );
17 die "property name must be bound" unless $args{name}->is_bound;
0676b282 18 my $name = $state->resolve_value($args{name});
896fd92e 19 if ($args{of}->is_bound) {
20 if ($args{value}->is_bound) {
0676b282 21 if ($state->resolve_value($args{of})->$name
22 eq $state->resolve_value($args{value})) {
deec7cc4 23 return $state->add_dependencies(
24 $args{of}->id => $args{value}->id,
25 $args{value}->id => $args{of}->id,
26 )
27 ->then($self->next);
896fd92e 28 }
29 return $state->backtrack;
30 }
0676b282 31 my $value = $state->resolve_value($args{of});
896fd92e 32 if ($value->can("has_${name}") and not $value->${\"has_${name}"}) {
33 return $state->backtrack;
34 }
165d0b2c 35 my $var_ref = DX::VarRef->new(var_id => $args{of}->id, derive => $name);
36 return $state->bind_value($args{value}->id, $var_ref)
deec7cc4 37 ->add_dependencies($args{value}->id => $args{of}->id)
38 ->then($self->next);
896fd92e 39 }
40 die "Can't yet handle unbound 'of' argument";
41}
42
431;