From 4c06900abdb7ebb70691e7ef7158b960a38fa77b Mon Sep 17 00:00:00 2001 From: reneeb Date: Wed, 13 Jul 2022 07:56:05 -0400 Subject: [PATCH] Implement replace method --- lib/PPI/Element.pm | 4 ++-- lib/PPI/Node.pm | 27 +++++++++++++++++++++++++-- t/ppi_element_replace.t | 2 -- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/lib/PPI/Element.pm b/lib/PPI/Element.pm index 043d826e..3e67d1c2 100644 --- a/lib/PPI/Element.pm +++ b/lib/PPI/Element.pm @@ -593,8 +593,8 @@ one being replaced. sub replace { my $self = ref $_[0] ? shift : return undef; - _INSTANCE(shift, ref $self) or return undef; - die "The ->replace method has not yet been implemented"; + my $replace = _INSTANCE(shift, ref $self) or return undef; + $self->parent->replace_child( $self, $replace ); } =pod diff --git a/lib/PPI/Node.pm b/lib/PPI/Node.pm index 8d1ca4d0..9f73ed84 100644 --- a/lib/PPI/Node.pm +++ b/lib/PPI/Node.pm @@ -522,6 +522,25 @@ sub remove_child { $child; } +=head2 replace_child $Element, $Replacement + +If successful, returns the replace element. Otherwise, returns C. + +=cut + +sub replace_child { + my $self = shift; + + my $child = _INSTANCE(shift, 'PPI::Element') or return undef; + my $replacement = _INSTANCE(shift, 'PPI::Element') or return undef; + + my $success = $self->__replace_child( $child, $replacement ); + + return if !$success; + return $replacement; +} + + =pod =head2 prune $class | \&wanted @@ -732,14 +751,18 @@ sub __replace_child { my $self = shift; my $key = refaddr shift; my $p = List::Util::first { - refaddr $self->{children}[$_] == $key - } 0..$#{$self->{children}}; + refaddr $self->{children}[$_] == $key + } 0..$#{$self->{children}}; + + return if !defined $p; + foreach ( @_ ) { Scalar::Util::weaken( $_PARENT{refaddr $_} = $self ); } splice( @{$self->{children}}, $p, 1, @_ ); + delete $_PARENT{$key}; 1; } diff --git a/t/ppi_element_replace.t b/t/ppi_element_replace.t index 34476e01..a8c6a06c 100755 --- a/t/ppi_element_replace.t +++ b/t/ppi_element_replace.t @@ -8,8 +8,6 @@ use PPI::Test::pragmas; use PPI::Document (); use Test::More; -local $TODO = 'Not yet implemented'; - __REPLACE: { my $Document = PPI::Document->new( \"print 'Hello World';" ); isa_ok( $Document, 'PPI::Document' );