add value_path method and give action builders a path
Matt S Trout [Wed, 16 Mar 2016 16:28:41 +0000 (16:28 +0000)]
lib/DX/ActionBuilder/Null.pm
lib/DX/Role/Value.pm
lib/DX/ShellSession.pm

index 3bcea18..0ac25b7 100644 (file)
@@ -4,7 +4,7 @@ use DX::Class;
 
 with 'DX::Role::ActionBuilder';
 
-sub target_path { [ 'N/A' ] }
+has target_path => (is => 'ro');
 
 sub can_set_value { 0 }
 
@@ -16,6 +16,27 @@ sub action_for_set_member { undef }
 
 sub action_for_remove_member { undef }
 
-sub specialize_for_member { $_[0] }
+sub specialize_for_member {
+  my ($self, $at) = @_;
+  return $self unless ref($self);
+  return $self unless my $path = $self->target_path;
+  return $self->but(
+    target_path => [ @{$self->target_path}, $at ]
+  );
+}
+
+sub apply_to_value {
+  my ($self, $value) = @_;
+  my $new_value = $value->but_set_action_builder($self)
+                        ->but_set_identity_path($self->target_path);
+  return $new_value unless $new_value->isa('DX::Value::Dict');
+  my %m = %{$new_value->members};
+  return $new_value->but(
+    members => {
+      map +($_ => $self->specialize_for_member($_)->apply_to_value($m{$_})),
+        keys %m,
+    },
+  );
+}
 
 1;
index 01fd710..018b956 100644 (file)
@@ -11,6 +11,8 @@ has action_builder => (
   handles => [ qw(can_set_value action_for_set_value) ],
 );
 
+sub value_path { shift->action_builder->target_path }
+
 sub is_set { 1 }
 
 sub but_set_action_builder {
index ecb93d8..eae1349 100644 (file)
@@ -86,7 +86,9 @@ has tcl => (is => 'lazy', builder => sub {
     my $tqs = $self->shell_state->template_query_state;
     my $new_tqs = $tqs->but(
       globals => $tqs->globals->with_member_at(
-        $name => $self->expand_args($value),
+        $name => DX::ActionBuilder::Null->new(
+                   target_path => [ $name ],
+                 )->apply_to_value($self->expand_args($value)),
       ),
     );
     $self->_set_shell_state(