7 PPI::Dumper - Dumping of PDOM trees
12 my $Module = PPI::Document->new( 'MyModule.pm' );
15 my $Dumper = PPI::Dumper->new( $Module );
22 The PDOM trees in PPI are quite complex, and getting a dump of their
23 structure for development and debugging purposes is important.
25 This module provides that functionality.
27 The process is relatively simple. Create a dumper object with a
28 particular set of options, and then call one of the dump methods to
29 generate the dump content itself.
36 use Params::Util qw{_INSTANCE};
38 use vars qw{$VERSION};
47 #####################################################################
52 =head2 new $Element, param => value, ...
54 The C<new> constructor creates a dumper, and takes as argument a single
55 L<PPI::Element> object of any type to serve as the root of the tree to
56 be dumped, and a number of key-E<gt>value parameters to control the output
57 format of the Dumper. Details of the parameters are listed below.
59 Returns a new C<PPI::Dumper> object, or C<undef> if the constructor
60 is not passed a correct L<PPI::Element> root object.
66 Should the dumper print the memory addresses of each PDOM element.
67 True/false value, off by default.
71 Should the structures being dumped be indented. This value is numeric,
72 with the number representing the number of spaces to use when indenting
73 the dumper output. Set to '2' by default.
77 Should the dumper print the full class for each element.
78 True/false value, on by default.
82 Should the dumper show the content of each element. True/false value,
87 Should the dumper show whitespace tokens. By not showing the copious
88 numbers of whitespace tokens the structure of the code can often be
89 made much clearer. True/false value, on by default.
93 Should the dumper show comment tokens. In situations where you have
94 a lot of comments, the code can often be made clearer by ignoring
95 comment tokens. True/value value, on by default.
99 Should the dumper show the location of each token. The values shown are
100 [ line, rowchar, column ]. See L<PPI::Element/"location"> for a description of
101 what these values really are. True/false value, off by default.
109 my $Element = _INSTANCE(shift, 'PPI::Element') or return undef;
115 memaddr => '', # Show the refaddr of the item
116 indent => 2, # Indent the structures
117 class => 1, # Show the object class
118 content => 1, # Show the object contents
119 whitespace => 1, # Show whitespace tokens
120 comments => 1, # Show comment tokens
121 locations => 0, # Show token locations
126 my %options = map { lc $_ } @_;
127 foreach ( keys %{$self->{display}} ) {
128 if ( exists $options{$_} ) {
129 if ( $_ eq 'indent' ) {
130 $self->{display}->{indent} = $options{$_};
132 $self->{display}->{$_} = !! $options{$_};
137 $self->{indent_string} = join '', (' ' x $self->{display}->{indent});
139 # Try to auto-call index_locations. If it failes, turn of locations display
140 if ( $self->{display}->{locations} ) {
141 my $Document = $Element->isa('PPI::Document') ? $Element : $Element->top;
142 if ( $Document->isa('PPI::Document') ) {
143 $Document->index_locations;
145 $self->{display}->{locations} = 0;
156 #####################################################################
157 # Main Interface Methods
163 The C<print> method generates the dump and prints it to STDOUT.
165 Returns as for the internal print function.
170 CORE::print(shift->string);
177 The C<string> method generates the dump and provides it as a
180 Returns a string or undef if there is an error while generating the dump.
185 my $array_ref = shift->_dump or return undef;
186 join '', map { "$_\n" } @$array_ref;
193 The C<list> method generates the dump and provides it as a raw
194 list, without trailing newlines.
196 Returns a list or the null list if there is an error while generation
202 my $array_ref = shift->_dump or return ();
210 #####################################################################
211 # Generation Support Methods
214 my $self = ref $_[0] ? shift : shift->new(shift);
215 my $Element = _INSTANCE($_[0], 'PPI::Element') ? shift : $self->{root};
216 my $indent = shift || '';
217 my $output = shift || [];
219 # Print the element if needed
221 if ( $Element->isa('PPI::Token::Whitespace') ) {
222 $show = 0 unless $self->{display}->{whitespace};
223 } elsif ( $Element->isa('PPI::Token::Comment') ) {
224 $show = 0 unless $self->{display}->{comments};
226 push @$output, $self->_element_string( $Element, $indent ) if $show;
228 # Recurse into our children
229 if ( $Element->isa('PPI::Node') ) {
230 my $child_indent = $indent . $self->{indent_string};
231 foreach my $child ( @{$Element->{children}} ) {
232 $self->_dump( $child, $child_indent, $output );
239 sub _element_string {
240 my $self = ref $_[0] ? shift : shift->new(shift);
241 my $Element = _INSTANCE($_[0], 'PPI::Element') ? shift : $self->{root};
242 my $indent = shift || '';
245 # Add the memory location
246 if ( $self->{display}->{memaddr} ) {
247 $string .= $Element->refaddr . ' ';
250 # Add the location if such exists
251 if ( $self->{display}->{locations} ) {
253 if ( $Element->isa('PPI::Token') ) {
254 my $location = $Element->location;
256 $loc_string = sprintf("[ % 4d, % 3d, % 3d ] ", @$location);
259 # Output location or pad with 20 spaces
260 $string .= $loc_string || " " x 20;
264 if ( $self->{display}->{indent} ) {
269 if ( $self->{display}->{class} ) {
270 $string .= ref $Element;
273 if ( $Element->isa('PPI::Token') ) {
275 if ( $self->{display}->{content} ) {
276 my $content = $Element->content;
277 $content =~ s/\n/\\n/g;
278 $content =~ s/\t/\\t/g;
279 $string .= " \t'$content'";
281 } elsif ( $Element->isa('PPI::Structure') ) {
283 if ( $self->{display}->{content} ) {
284 my $start = $Element->start
285 ? $Element->start->content
287 my $finish = $Element->finish
288 ? $Element->finish->content
290 $string .= " \t$start ... $finish";
303 See the L<support section|PPI/SUPPORT> in the main module.
307 Adam Kennedy E<lt>adamk@cpan.orgE<gt>
311 Copyright 2001 - 2009 Adam Kennedy.
313 This program is free software; you can redistribute
314 it and/or modify it under the same terms as Perl itself.
316 The full text of the license can be found in the
317 LICENSE file included with this module.