Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the PPI CPAN distribution.

Report information
The Basics
Id: 91274
Status: new
Priority: 0/
Queue: PPI

People
Owner: Nobody in particular
Requestors: LACKITA [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: add_element_at method for PPI::Node
I'm working on some refactoring tools built on top of PPI, and being able to add a child in the middle of a node would be really helpful. I've attached a patch accomplishing this, I'm happy to incorporate any suggestions you have.
Subject: add_element_at.patch
Index: t/04_element.t =================================================================== --- t/04_element.t (revision 15837) +++ t/04_element.t (working copy) @@ -16,7 +16,7 @@ use PPI::Lexer (); # Execute the tests -use Test::More tests => 221; +use Test::More tests => 222; use Test::NoWarnings; use Scalar::Util 'refaddr'; @@ -450,6 +450,14 @@ is( $k3, $k1, 'PARENT keys returns to original on DESTROY' ); } +# Then, add an element in the middle of a node +SCOPE: { + my $d = PPI::Lexer->lex_source("1 + 1;\n2 + 2;"); + my $Token = PPI::Token::Number->new( '1' ); + $d->add_element_at(1, $Token); + is( $Token, $d->child(1), 'add_element_at should insert at the specified position' ); +} + # Repeat for an entire (large) file SCOPE: { my $k1 = scalar keys %PPI::Element::_PARENT; Index: lib/PPI.pm =================================================================== --- lib/PPI.pm (revision 15837) +++ lib/PPI.pm (working copy) @@ -8,7 +8,7 @@ # Set the version for CPAN use vars qw{$VERSION $XS_COMPATIBLE @XS_EXCLUDE}; BEGIN { - $VERSION = '1.216_01'; + $VERSION = '1.216_02'; $XS_COMPATIBLE = '0.845'; @XS_EXCLUDE = (); } Index: lib/PPI/Node.pm =================================================================== --- lib/PPI/Node.pm (revision 15837) +++ lib/PPI/Node.pm (working copy) @@ -134,6 +134,36 @@ =pod +=head2 add_element_at $index, $Element + +The C<add_element_at> method adds a L<PPI::Element> object to a +C<PPI::Node> between the elements at positions $index-1 and $index. + +Returns true if the L<PPI::Element> was added. Returns C<undef> if the +Element was already within another Node, or the method is not passed +a L<PPI::Element> object. + +=cut + +sub add_element_at { + my $self = shift; + my $index = shift; + + # Check the element + my $Element = _INSTANCE(shift, 'PPI::Element') or return undef; + $_PARENT{refaddr $Element} and return undef; + + # Add the argument to the elements + splice @{$self->{children}}, $index, 0, $Element; + Scalar::Util::weaken( + $_PARENT{refaddr $Element} = $self + ); + + 1; +} + +=pod + =head2 elements The C<elements> method accesses all child elements B<structurally> within
On Mon Dec 09 07:51:31 2013, LACKITA wrote: Show quoted text
> I'm working on some refactoring tools built on top of PPI, and being > able to add a child in the middle of a node would be really helpful. > I've attached a patch accomplishing this, I'm happy to incorporate any > suggestions you have.
Actually, one thing confuses me. I mimicked add_element when I created the new method, but I don't know why the reference is weakened. When I try to add a newly created element it ends up getting reclaimed by the destructor once the refactoring method falls out of scope.