From: Matt S Trout Date: Sat, 5 Mar 2016 21:48:39 +0000 (+0000) Subject: disturbingly, bound values appear to actually work X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=1e90aa036af7c0b6d27558e27ff44b268e307afa;p=scpubgit%2FDX.git disturbingly, bound values appear to actually work --- diff --git a/fragments/bind b/fragments/bind new file mode 100644 index 0000000..d3d9d24 --- /dev/null +++ b/fragments/bind @@ -0,0 +1,7 @@ +? +is_dict ?X +eq ?Y X +qact +eq Y {{ foo 1 }} +qact +. diff --git a/lib/DX/Action/BindValue.pm b/lib/DX/Action/BindValue.pm new file mode 100644 index 0000000..a355935 --- /dev/null +++ b/lib/DX/Action/BindValue.pm @@ -0,0 +1,20 @@ +package DX::Action::BindValue; + +use DX::Update::SetValue; +use DX::ActionBuilder::BoundValue; +use DX::Class; + +with 'DX::Role::SimpleAction'; + +has new_value => (is => 'ro', required => 1); + +sub _build__updates { + my ($self) = @_; + DX::Update::SetValue->new( + target_path => $self->target_path, + new_value => $self->new_value, + ); +} + +1; + diff --git a/lib/DX/Action/SetBoundValue.pm b/lib/DX/Action/SetBoundValue.pm new file mode 100644 index 0000000..dbc0d75 --- /dev/null +++ b/lib/DX/Action/SetBoundValue.pm @@ -0,0 +1,51 @@ +package DX::Action::SetBoundValue; + +use DX::Update::SetValue; +use DX::Class; + +with 'DX::Role::Action'; + +has target_path => (is => 'ro', required => 1); + +has rebind_path => (is => 'ro', required => 1); + +has new_value => (is => 'ro', required => 1); + +has inner_action => (is => 'ro', required => 1); + +sub dry_run { + my ($self, $hyp) = @_; + my ($outer_hyp, @inner_events) = $self->inner_action->dry_run($hyp); + my ($scope, @events) = $outer_hyp->scope->apply_updates( + DX::Update::SetValue->new( + target_path => $self->target_path, + new_value => $self->new_value, + ) + ); + my $new_bound = do { + my $targ = $scope; + $targ = $targ->get_member_at($_) for @{$self->rebind_path}; + $targ; + }; + my @actions = @{$outer_hyp->actions}; + foreach my $idx (0.. $#actions) { + my $act = $actions[$idx]; + if ( + $act->isa('DX::Action::BindValue') + and join("\0", @{$act->target_path}) + eq join("\0", @{$self->rebind_path}) + ) { + my $bind = splice @actions, $idx, 1; + push @actions, $bind->but(new_value => $new_bound); + last; + } + } + return ( + $outer_hyp->but(scope => $scope, actions => \@actions), + @inner_events, @events + ); +} + +sub run { die } + +1; diff --git a/lib/DX/ActionBuilder/BoundValue.pm b/lib/DX/ActionBuilder/BoundValue.pm new file mode 100644 index 0000000..8454992 --- /dev/null +++ b/lib/DX/ActionBuilder/BoundValue.pm @@ -0,0 +1,30 @@ +package DX::ActionBuilder::BoundValue; + +use DX::Action::SetBoundValue; +#use DX::Action::AddBoundValue; +use DX::Class; + +with 'DX::Role::ActionBuilder'; + +has target_path => (is => 'ro', required => 1); + +has rebind_path => (is => 'ro', required => 1); + +has bound_to_path => (is => 'ro', required => 1); + +has inner_action_builder => (is => 'ro', required => 1); + +sub action_for_set_value { + my ($self, $value) = @_; + my $inner_action = $self->inner_action_builder->action_for_set_value($value); + return undef unless $inner_action; + DX::Action::SetBoundValue->new( + target_path => $self->target_path, + rebind_path => $self->rebind_path, + new_value => $value->but_set_action_builder($self) + ->but_set_identity_path($self->bound_to_path), + inner_action => $inner_action, + ) +} + +1; diff --git a/lib/DX/ActionBuilder/UnsetValue.pm b/lib/DX/ActionBuilder/UnsetValue.pm index c00a7fb..acc9306 100644 --- a/lib/DX/ActionBuilder/UnsetValue.pm +++ b/lib/DX/ActionBuilder/UnsetValue.pm @@ -2,6 +2,8 @@ package DX::ActionBuilder::UnsetValue; use DX::Action::SetValue; use DX::ActionBuilder::Normal; +use DX::Action::BindValue; +use DX::ActionBuilder::BoundValue; use DX::Class; with 'DX::Role::ActionBuilder'; @@ -10,8 +12,17 @@ has target_path => (is => 'ro', required => 1); sub action_for_set_value { my ($self, $value) = @_; - if (0) { # value_path / identity_path test - # bind value + if (my $p = $value->identity_path) { + my $ab = DX::ActionBuilder::BoundValue->new( + target_path => $self->target_path, + rebind_path => $self->target_path, + bound_to_path => $p, + inner_action_builder => $value->action_builder, + ); + return DX::Action::BindValue->new( + target_path => $self->target_path, + new_value => $value->but_set_action_builder($ab), + ) } my $ab = DX::ActionBuilder::Normal->new( target_path => $self->target_path, diff --git a/lib/DX/Deparse.pm b/lib/DX/Deparse.pm index ff590f9..1096792 100644 --- a/lib/DX/Deparse.pm +++ b/lib/DX/Deparse.pm @@ -110,6 +110,11 @@ sub _fmt_action_addvalue { $self->_fmt_action_generic(AddValue => $action, $meta); } +sub _fmt_action_bindvalue { + my ($self, $action, $meta) = @_; + $self->_fmt_action_generic(BindValue => $action, $meta); +} + sub _fmt_action_generic { my ($self, $name, $action, $meta) = @_; my $path = join '.', map $self->_fmt($_, $meta), @{$action->target_path}; diff --git a/lib/DX/ShellSession.pm b/lib/DX/ShellSession.pm index adced53..d90117a 100644 --- a/lib/DX/ShellSession.pm +++ b/lib/DX/ShellSession.pm @@ -47,6 +47,12 @@ has tcl => (is => 'lazy', builder => sub { push our @Result, [ output => $rps ]; return; }); + $tcl->CreateCommand(qact => sub { + my $act = $self->shell_state->current_query_state->search_state + ->current_hypothesis->actions; + push our @Result, map [ output => $_ ], @$act; + return; + }); foreach my $pred ( keys %{$self->shell_state->template_query_state->predicates} ) {