1PPI(3)                User Contributed Perl Documentation               PPI(3)
2
3
4

NAME

6       PPI - Parse, Analyze and Manipulate Perl (without perl)
7

SYNOPSIS

9         use PPI;
10
11         # Create a new empty document
12         my $Document = PPI::Document->new;
13
14         # Create a document from source
15         $Document = PPI::Document->new(\'print "Hello World!\n"');
16
17         # Load a Document from a file
18         $Document = PPI::Document->new('Module.pm');
19
20         # Does it contain any POD?
21         if ( $Document->find_any('PPI::Token::Pod') ) {
22             print "Module contains POD\n";
23         }
24
25         # Get the name of the main package
26         $pkg = $Document->find_first('PPI::Statement::Package')->namespace;
27
28         # Remove all that nasty documentation
29         $Document->prune('PPI::Token::Pod');
30         $Document->prune('PPI::Token::Comment');
31
32         # Save the file
33         $Document->save('Module.pm.stripped');
34

DESCRIPTION

36   About this Document
37       This is the PPI manual. It describes its reason for existing, its
38       general structure, its use, an overview of the API, and provides a few
39       implementation samples.
40
41   Background
42       The ability to read, and manipulate Perl (the language)
43       programmatically other than with perl (the application) was one that
44       caused difficulty for a long time.
45
46       The cause of this problem was Perl's complex and dynamic grammar.
47       Although there is typically not a huge diversity in the grammar of most
48       Perl code, certain issues cause large problems when it comes to
49       parsing.
50
51       Indeed, quite early in Perl's history Tom Christiansen introduced the
52       Perl community to the quote "Nothing but perl can parse Perl", or as it
53       is more often stated now as a truism:
54
55       "Only perl can parse Perl"
56
57       One example of the sorts of things the prevent Perl being easily parsed
58       are function signatures, as demonstrated by the following.
59
60         @result = (dothis $foo, $bar);
61
62         # Which of the following is it equivalent to?
63         @result = (dothis($foo), $bar);
64         @result = dothis($foo, $bar);
65
66       The first line above can be interpreted in two different ways,
67       depending on whether the &dothis function is expecting one argument, or
68       two, or several.
69
70       A "code parser" (something that parses for the purpose of execution)
71       such as perl needs information that is not found in the immediate
72       vicinity of the statement being parsed.
73
74       The information might not just be elsewhere in the file, it might not
75       even be in the same file at all. It might also not be able to determine
76       this information without the prior execution of a "BEGIN {}" block, or
77       the loading and execution of one or more external modules. Or worse the
78       &dothis function may not even have been written yet.
79
80       When parsing Perl as code, you must also execute it
81
82       Even perl itself never really fully understands the structure of the
83       source code after and indeed as it processes it, and in that sense
84       doesn't "parse" Perl source into anything remotely like a structured
85       document.  This makes it of no real use for any task that needs to
86       treat the source code as a document, and do so reliably and robustly.
87
88       For more information on why it is impossible to parse perl, see Randal
89       Schwartz's seminal response to the question of "Why can't you parse
90       Perl".
91
92       <http://www.perlmonks.org/index.pl?node_id=44722>
93
94       The purpose of PPI is not to parse Perl Code, but to parse Perl
95       Documents. By treating the problem this way, we are able to parse a
96       single file containing Perl source code "isolated" from any other
97       resources, such as libraries upon which the code may depend, and
98       without needing to run an instance of perl alongside or inside the
99       parser.
100
101       Historically, using an embedded perl parser was widely considered to be
102       the most likely avenue for finding a solution to parsing Perl. It has
103       been investigated from time to time, but attempts have generally failed
104       or suffered from sufficiently bad corner cases that they were
105       abandoned.
106
107   What Does PPI Stand For?
108       "PPI" is an acronym for the longer original module name
109       "Parse::Perl::Isolated". And in the spirit or the silly acronym games
110       played by certain unnamed Open Source projects you may have hurd of, it
111       also a reverse backronym of "I Parse Perl".
112
113       Of course, I could just be lying and have just made that second bit up
114       10 minutes before the release of PPI 1.000. Besides, all the cool Perl
115       packages have TLAs (Three Letter Acronyms). It's a rule or something.
116
117       Why don't you just think of it as the Perl Parsing Interface for
118       simplicity.
119
120       The original name was shortened to prevent the author (and you the
121       users) from contracting RSI by having to type crazy things like
122       "Parse::Perl::Isolated::Token::QuoteLike::Backtick" 100 times a day.
123
124       In acknowledgment that someone may some day come up with a valid
125       solution for the grammar problem it was decided at the commencement of
126       the project to leave the "Parse::Perl" namespace free for any such
127       effort.
128
129       Since that time I've been able to prove to my own satisfaction that it
130       is truly impossible to accurately parse Perl as both code and document
131       at once. For the academics, parsing Perl suffers from the "Halting
132       Problem".
133
134   Why Parse Perl?
135       Once you can accept that we will never be able to parse Perl well
136       enough to meet the standards of things that treat Perl as code, it is
137       worth re-examining "why" we want to "parse" Perl at all.
138
139       What are the things that people might want a "Perl parser" for.
140
141       Documentation
142           Analyzing the contents of a Perl document to automatically generate
143           documentation, in parallel to, or as a replacement for, POD
144           documentation.
145
146           Allow an indexer to locate and process all the comments and
147           documentation from code for "full text search" applications.
148
149       Structural and Quality Analysis
150           Determine quality or other metrics across a body of code, and
151           identify situations relating to particular phrases, techniques or
152           locations.
153
154           Index functions, variables and packages within Perl code, and doing
155           search and graph (in the node/edge sense) analysis of large code
156           bases.
157
158           Perl::Critic, based on PPI, is a large, thriving tool for bug
159           detection and style analysis of Perl code.
160
161       Refactoring
162           Make structural, syntax, or other changes to code in an automated
163           manner, either independently or in assistance to an editor. This
164           sort of task list includes backporting, forward porting, partial
165           evaluation, "improving" code, or whatever. All the sort of things
166           you'd want from a Perl::Editor.
167
168       Layout
169           Change the layout of code without changing its meaning. This
170           includes techniques such as tidying (like perltidy), obfuscation,
171           compressing and "squishing", or to implement formatting preferences
172           or policies.
173
174       Presentation
175           This includes methods of improving the presentation of code,
176           without changing the content of the code. Modify, improve, syntax
177           colour etc the presentation of a Perl document. Generating
178           "IntelliText"-like functions.
179
180       If we treat this as a baseline for the sort of things we are going to
181       have to build on top of Perl, then it becomes possible to identify a
182       standard for how good a Perl parser needs to be.
183
184   How good is Good Enough(TM)
185       PPI seeks to be good enough to achieve all of the above tasks, or to
186       provide a sufficiently good API on which to allow others to implement
187       modules in these and related areas.
188
189       However, there are going to be limits to this process. Because PPI
190       cannot adapt to changing grammars, any code written using source
191       filters should not be assumed to be parsable.
192
193       At one extreme, this includes anything munged by Acme::Bleach, as well
194       as (arguably) more common cases like Switch. We do not pretend to be
195       able to always parse code using these modules, although as long as it
196       still follows a format that looks like Perl syntax, it may be possible
197       to extend the lexer to handle them.
198
199       The ability to extend PPI to handle lexical additions to the language
200       is on the drawing board to be done some time post-1.0
201
202       The goal for success was originally to be able to successfully parse
203       99% of all Perl documents contained in CPAN. This means the entire file
204       in each case.
205
206       PPI has succeeded in this goal far beyond the expectations of even the
207       author. At time of writing there are only 28 non-Acme Perl modules in
208       CPAN that PPI is incapable of parsing. Most of these are so badly
209       broken they do not compile as Perl code anyway.
210
211       So unless you are actively going out of your way to break PPI, you
212       should expect that it will handle your code just fine.
213
214   Internationalisation
215       PPI provides partial support for internationalisation and localisation.
216
217       Specifically, it allows the use characters from the Latin-1 character
218       set to be used in quotes, comments, and POD. Primarily, this covers
219       languages from Europe and South America.
220
221       PPI does not currently provide support for Unicode.  If you need
222       Unicode support and would like to help, contact the author. (contact
223       details below)
224
225   Round Trip Safe
226       When PPI parses a file it builds everything into the model, including
227       whitespace. This is needed in order to make the Document fully "Round
228       Trip" safe.
229
230       The general concept behind a "Round Trip" parser is that it knows what
231       it is parsing is somewhat uncertain, and so expects to get things wrong
232       from time to time. In the cases where it parses code wrongly the tree
233       will serialize back out to the same string of code that was read in,
234       repairing the parser's mistake as it heads back out to the file.
235
236       The end result is that if you parse in a file and serialize it back out
237       without changing the tree, you are guaranteed to get the same file you
238       started with. PPI does this correctly and reliably for 100% of all
239       known cases.
240
241       What goes in, will come out. Every time.
242
243       The one minor exception at this time is that if the newlines for your
244       file are wrong (meaning not matching the platform newline format), PPI
245       will localise them for you. (It isn't to be convenient, supporting
246       arbitrary newlines would make some of the code more complicated)
247
248       Better control of the newline type is on the wish list though, and
249       anyone wanting to help out is encouraged to contact the author.
250

IMPLEMENTATION

252   General Layout
253       PPI is built upon two primary "parsing" components, PPI::Tokenizer and
254       PPI::Lexer, and a large tree of about 50 classes which implement the
255       various the Perl Document Object Model (PDOM).
256
257       The PDOM is conceptually similar in style and intent to the regular DOM
258       or other code Abstract Syntax Trees (ASTs), but contains some
259       differences to handle perl-specific cases, and to assist in treating
260       the code as a document. Please note that it is not an implementation of
261       the official Document Object Model specification, only somewhat similar
262       to it.
263
264       On top of the Tokenizer, Lexer and the classes of the PDOM, sit a
265       number of classes intended to make life a little easier when dealing
266       with PDOM trees.
267
268       Both the major parsing components were hand-coded from scratch with
269       only plain Perl code and a few small utility modules. There are no
270       grammar or patterns mini-languages, no YACC or LEX style tools and only
271       a small number of regular expressions.
272
273       This is primarily because of the sheer volume of accumulated cruft that
274       exists in Perl. Not even perl itself is capable of parsing Perl
275       documents (remember, it just parses and executes it as code).
276
277       As a result, PPI needed to be cruftier than perl itself. Feel free to
278       shudder at this point, and hope you never have to understand the
279       Tokenizer codebase. Speaking of which...
280
281   The Tokenizer
282       The Tokenizer takes source code and converts it into a series of
283       tokens. It does this using a slow but thorough character by character
284       manual process, rather than using a pattern system or complex regexes.
285
286       Or at least it does so conceptually. If you were to actually trace the
287       code you would find it's not truly character by character due to a
288       number of regexps and optimisations throughout the code. This lets the
289       Tokenizer "skip ahead" when it can find shortcuts, so it tends to jump
290       around a line a bit wildly at times.
291
292       In practice, the number of times the Tokenizer will actually move the
293       character cursor itself is only about 5% - 10% higher than the number
294       of tokens contained in the file. This makes it about as optimal as it
295       can be made without implementing it in something other than Perl.
296
297       In 2001 when PPI was started, this structure made PPI quite slow, and
298       not really suitable for interactive tasks. This situation has improved
299       greatly with multi-gigahertz processors, but can still be painful when
300       working with very large files.
301
302       The target parsing rate for PPI is about 5000 lines per gigacycle. It
303       is currently believed to be at about 1500, and main avenue for making
304       it to the target speed has now become PPI::XS, a drop-in XS accelerator
305       for PPI.
306
307       Since PPI::XS has only just gotten off the ground and is currently only
308       at proof-of-concept stage, this may take a little while. Anyone
309       interested in helping out with PPI::XS is highly encouraged to contact
310       the author. In fact, the design of PPI::XS means it's possible to port
311       one function at a time safely and reliably. So every little bit will
312       help.
313
314   The Lexer
315       The Lexer takes a token stream, and converts it to a lexical tree.
316       Because we are parsing Perl documents this includes whitespace,
317       comments, and all number of weird things that have no relevance when
318       code is actually executed.
319
320       An instantiated PPI::Lexer consumes PPI::Tokenizer objects and produces
321       PPI::Document objects. However you should probably never be working
322       with the Lexer directly. You should just be able to create
323       PPI::Document objects and work with them directly.
324
325   The Perl Document Object Model
326       The PDOM is a structured collection of data classes that together
327       provide a correct and scalable model for documents that follow the
328       standard Perl syntax.
329
330   The PDOM Class Tree
331       The following lists all of the 67 current PDOM classes, listing with
332       indentation based on inheritance.
333
334          PPI::Element
335             PPI::Node
336                PPI::Document
337                   PPI::Document::Fragment
338                PPI::Statement
339                   PPI::Statement::Package
340                   PPI::Statement::Include
341                   PPI::Statement::Sub
342                      PPI::Statement::Scheduled
343                   PPI::Statement::Compound
344                   PPI::Statement::Break
345                   PPI::Statement::Given
346                   PPI::Statement::When
347                   PPI::Statement::Data
348                   PPI::Statement::End
349                   PPI::Statement::Expression
350                      PPI::Statement::Variable
351                   PPI::Statement::Null
352                   PPI::Statement::UnmatchedBrace
353                   PPI::Statement::Unknown
354                PPI::Structure
355                   PPI::Structure::Block
356                   PPI::Structure::Subscript
357                   PPI::Structure::Constructor
358                   PPI::Structure::Condition
359                   PPI::Structure::List
360                   PPI::Structure::For
361                   PPI::Structure::Given
362                   PPI::Structure::When
363                   PPI::Structure::Unknown
364             PPI::Token
365                PPI::Token::Whitespace
366                PPI::Token::Comment
367                PPI::Token::Pod
368                PPI::Token::Number
369                   PPI::Token::Number::Binary
370                   PPI::Token::Number::Octal
371                   PPI::Token::Number::Hex
372                   PPI::Token::Number::Float
373                      PPI::Token::Number::Exp
374                   PPI::Token::Number::Version
375                PPI::Token::Word
376                PPI::Token::DashedWord
377                PPI::Token::Symbol
378                   PPI::Token::Magic
379                PPI::Token::ArrayIndex
380                PPI::Token::Operator
381                PPI::Token::Quote
382                   PPI::Token::Quote::Single
383                   PPI::Token::Quote::Double
384                   PPI::Token::Quote::Literal
385                   PPI::Token::Quote::Interpolate
386                PPI::Token::QuoteLike
387                   PPI::Token::QuoteLike::Backtick
388                   PPI::Token::QuoteLike::Command
389                   PPI::Token::QuoteLike::Regexp
390                   PPI::Token::QuoteLike::Words
391                   PPI::Token::QuoteLike::Readline
392                PPI::Token::Regexp
393                   PPI::Token::Regexp::Match
394                   PPI::Token::Regexp::Substitute
395                   PPI::Token::Regexp::Transliterate
396                PPI::Token::HereDoc
397                PPI::Token::Cast
398                PPI::Token::Structure
399                PPI::Token::Label
400                PPI::Token::Separator
401                PPI::Token::Data
402                PPI::Token::End
403                PPI::Token::Prototype
404                PPI::Token::Attribute
405                PPI::Token::Unknown
406
407       To summarize the above layout, all PDOM objects inherit from the
408       PPI::Element class.
409
410       Under this are PPI::Token, strings of content with a known type, and
411       PPI::Node, syntactically significant containers that hold other
412       Elements.
413
414       The three most important of these are the PPI::Document, the
415       PPI::Statement and the PPI::Structure classes.
416
417   The Document, Statement and Structure
418       At the top of all complete PDOM trees is a PPI::Document object. It
419       represents a complete file of Perl source code as you might find it on
420       disk.
421
422       There are some specialised types of document, such as
423       PPI::Document::File and PPI::Document::Normalized but for the purposes
424       of the PDOM they are all just considered to be the same thing.
425
426       Each Document will contain a number of Statements, Structures and
427       Tokens.
428
429       A PPI::Statement is any series of Tokens and Structures that are
430       treated as a single contiguous statement by perl itself. You should
431       note that a Statement is as close as PPI can get to "parsing" the code
432       in the sense that perl-itself parses Perl code when it is building the
433       op-tree.
434
435       Because of the isolation and Perl's syntax, it is provably impossible
436       for PPI to accurately determine precedence of operators or which tokens
437       are implicit arguments to a sub call.
438
439       So rather than lead you on with a bad guess that has a strong chance of
440       being wrong, PPI does not attempt to determine precedence or sub
441       parameters at all.
442
443       At a fundamental level, it only knows that this series of elements
444       represents a single Statement as perl sees it, but it can do so with
445       enough certainty that it can be trusted.
446
447       However, for specific Statement types the PDOM is able to derive
448       additional useful information about their meaning. For the best, most
449       useful, and most heavily used example, see PPI::Statement::Include.
450
451       A PPI::Structure is any series of tokens contained within matching
452       braces.  This includes code blocks, conditions, function argument
453       braces, anonymous array and hash constructors, lists, scoping braces
454       and all other syntactic structures represented by a matching pair of
455       braces, including (although it may not seem obvious at first)
456       "<READLINE>" braces.
457
458       Each Structure contains none, one, or many Tokens and Structures (the
459       rules for which vary for the different Structure subclasses)
460
461       Under the PDOM structure rules, a Statement can never directly contain
462       another child Statement, a Structure can never directly contain another
463       child Structure, and a Document can never contain another Document
464       anywhere in the tree.
465
466       Aside from these three rules, the PDOM tree is extremely flexible.
467
468   The PDOM at Work
469       To demonstrate the PDOM in use lets start with an example showing how
470       the tree might look for the following chunk of simple Perl code.
471
472         #!/usr/bin/perl
473
474         print( "Hello World!" );
475
476         exit();
477
478       Translated into a PDOM tree it would have the following structure (as
479       shown via the included PPI::Dumper).
480
481         PPI::Document
482           PPI::Token::Comment                '#!/usr/bin/perl\n'
483           PPI::Token::Whitespace             '\n'
484           PPI::Statement
485             PPI::Token::Word                 'print'
486             PPI::Structure::List             ( ... )
487               PPI::Token::Whitespace         ' '
488               PPI::Statement::Expression
489                 PPI::Token::Quote::Double    '"Hello World!"'
490               PPI::Token::Whitespace         ' '
491             PPI::Token::Structure            ';'
492           PPI::Token::Whitespace             '\n'
493           PPI::Token::Whitespace             '\n'
494           PPI::Statement
495             PPI::Token::Word                 'exit'
496             PPI::Structure::List             ( ... )
497             PPI::Token::Structure            ';'
498           PPI::Token::Whitespace             '\n'
499
500       Please note that in this example, strings are only listed for the
501       actual PPI::Token that contains that string. Structures are listed with
502       the type of brace characters it represents noted.
503
504       The PPI::Dumper module can be used to generate similar trees yourself.
505
506       We can make that PDOM dump a little easier to read if we strip out all
507       the whitespace. Here it is again, sans the distracting whitespace
508       tokens.
509
510         PPI::Document
511           PPI::Token::Comment                '#!/usr/bin/perl\n'
512           PPI::Statement
513             PPI::Token::Word                 'print'
514             PPI::Structure::List             ( ... )
515               PPI::Statement::Expression
516                 PPI::Token::Quote::Double    '"Hello World!"'
517             PPI::Token::Structure            ';'
518           PPI::Statement
519             PPI::Token::Word                 'exit'
520             PPI::Structure::List             ( ... )
521             PPI::Token::Structure            ';'
522
523       As you can see, the tree can get fairly deep at time, especially when
524       every isolated token in a bracket becomes its own statement. This is
525       needed to allow anything inside the tree the ability to grow. It also
526       makes the search and analysis algorithms much more flexible.
527
528       Because of the depth and complexity of PDOM trees, a vast number of
529       very easy to use methods have been added wherever possible to help
530       people working with PDOM trees do normal tasks relatively quickly and
531       efficiently.
532
533   Overview of the Primary Classes
534       The main PPI classes, and links to their own documentation, are listed
535       here in alphabetical order.
536
537       PPI::Document
538           The Document object, the root of the PDOM.
539
540       PPI::Document::Fragment
541           A cohesive fragment of a larger Document. Although not of any real
542           current use, it is needed for use in certain internal tree
543           manipulation algorithms.
544
545           For example, doing things like cut/copy/paste etc. Very similar to
546           a PPI::Document, but has some additional methods and does not
547           represent a lexical scope boundary.
548
549           A document fragment is also non-serializable, and so cannot be
550           written out to a file.
551
552       PPI::Dumper
553           A simple class for dumping readable debugging versions of PDOM
554           structures, such as in the demonstration above.
555
556       PPI::Element
557           The Element class is the abstract base class for all objects within
558           the PDOM
559
560       PPI::Find
561           Implements an instantiable object form of a PDOM tree search.
562
563       PPI::Lexer
564           The PPI Lexer. Converts Token streams into PDOM trees.
565
566       PPI::Node
567           The Node object, the abstract base class for all PDOM objects that
568           can contain other Elements, such as the Document, Statement and
569           Structure objects.
570
571       PPI::Statement
572           The base class for all Perl statements. Generic "evaluate for side-
573           effects" statements are of this actual type. Other more interesting
574           statement types belong to one of its children.
575
576           See its own documentation for a longer description and list of all
577           of the different statement types and sub-classes.
578
579       PPI::Structure
580           The abstract base class for all structures. A Structure is a
581           language construct consisting of matching braces containing a set
582           of other elements.
583
584           See the PPI::Structure documentation for a description and list of
585           all of the different structure types and sub-classes.
586
587       PPI::Token
588           A token is the basic unit of content. At its most basic, a Token is
589           just a string tagged with metadata (its class, and some additional
590           flags in some cases).
591
592       PPI::Token::_QuoteEngine
593           The PPI::Token::Quote and PPI::Token::QuoteLike classes provide
594           abstract base classes for the many and varied types of quote and
595           quote-like things in Perl. However, much of the actual quote login
596           is implemented in a separate quote engine, based at
597           PPI::Token::_QuoteEngine.
598
599           Classes that inherit from PPI::Token::Quote, PPI::Token::QuoteLike
600           and PPI::Token::Regexp are generally parsed only by the Quote
601           Engine.
602
603       PPI::Tokenizer
604           The PPI Tokenizer. One Tokenizer consumes a chunk of text and
605           provides access to a stream of PPI::Token objects.
606
607           The Tokenizer is very very complicated, to the point where even the
608           author treads carefully when working with it.
609
610           Most of the complication is the result of optimizations which have
611           tripled the tokenization speed, at the expense of maintainability.
612           We cope with the spaghetti by heavily commenting everything.
613
614       PPI::Transform
615           The Perl Document Transformation API. Provides a standard interface
616           and abstract base class for objects and classes that manipulate
617           Documents.
618

INSTALLING

620       The core PPI distribution is pure Perl and has been kept as tight as
621       possible and with as few dependencies as possible.
622
623       It should download and install normally on any platform from within the
624       CPAN and CPANPLUS applications, or directly using the distribution
625       tarball. If installing by hand, you may need to install a few small
626       utility modules first. The exact ones will depend on your version of
627       perl.
628
629       There are no special install instructions for PPI, and the normal "Perl
630       Makefile.PL", "make", "make test", "make install" instructions apply.
631

EXTENDING

633       The PPI namespace itself is reserved for use by PPI itself.  You are
634       recommended to use the PPIx:: namespace for PPI-specific modifications
635       or prototypes thereof, or Perl:: for modules which provide a general
636       Perl language-related functions.
637
638       If what you wish to implement looks like it fits into the PPIx::
639       namespace, you should consider contacting the PPI maintainers on GitHub
640       first, as what you want may already be in progress, or you may wish to
641       consider contributing to PPI itself.
642

TO DO

644       - Many more analysis and utility methods for PDOM classes
645
646       - Creation of a PPI::Tutorial document
647
648       - Add many more key functions to PPI::XS
649
650       - We can always write more and better unit tests
651
652       - Complete the full implementation of ->literal (1.200)
653
654       - Full understanding of scoping (due 1.300)
655

SUPPORT

657       The most recent version of PPI is available at the following address.
658
659       <http://search.cpan.org/~mithaldu/PPI/>
660
661       PPI source is maintained in a GitHub repository at the following
662       address.
663
664       <https://github.com/adamkennedy/PPI>
665
666       Contributions via GitHub pull request are welcome.
667
668       Bug fixes in the form of pull requests or bug reports with new
669       (failing) unit tests have the best chance of being addressed by busy
670       maintainers, and are strongly encouraged.
671
672       If you cannot provide a test or fix, or don't have time to do so, then
673       regular bug reports are still accepted and appreciated via the GitHub
674       bug tracker.
675
676       <https://github.com/adamkennedy/PPI/issues>
677
678       The "ppidump" utility that is part of the Perl::Critic distribution is
679       a useful tool for demonstrating how PPI is parsing (or misparsing)
680       small code snippets, and for providing information for bug reports.
681
682       For other issues, questions, or commercial or media-related enquiries,
683       contact the author.
684

AUTHOR

686       Adam Kennedy <adamk@cpan.org>
687

ACKNOWLEDGMENTS

689       A huge thank you to Phase N Australia (<http://phase-n.com/>) for
690       permitting the original open sourcing and release of this distribution
691       from what was originally several thousand hours of commercial work.
692
693       Another big thank you to The Perl Foundation
694       (<http://www.perlfoundation.org/>) for funding for the final big
695       refactoring and completion run.
696
697       Also, to the various co-maintainers that have contributed both large
698       and small with tests and patches and especially to those rare few who
699       have deep-dived into the guts to (gasp) add a feature.
700
701         - Dan Brook       : PPIx::XPath, Acme::PerlML
702         - Audrey Tang     : "Line Noise" Testing
703         - Arjen Laarhoven : Three-element ->location support
704         - Elliot Shank    : Perl 5.10 support, five-element ->location
705
706       And finally, thanks to those brave ( and foolish :) ) souls willing to
707       dive in and use, test drive and provide feedback on PPI before version
708       1.000, in some cases before it made it to beta quality, and still did
709       extremely distasteful things (like eating 50 meg of RAM a second).
710
711       I owe you all a beer. Corner me somewhere and collect at your
712       convenience.  If I missed someone who wasn't in my email history, thank
713       you too :)
714
715         # In approximate order of appearance
716         - Claes Jacobsson
717         - Michael Schwern
718         - Jeff T. Parsons
719         - CPAN Author "CHOCOLATEBOY"
720         - Robert Rotherberg
721         - CPAN Author "PODMASTER"
722         - Richard Soderberg
723         - Nadim ibn Hamouda el Khemir
724         - Graciliano M. P.
725         - Leon Brocard
726         - Jody Belka
727         - Curtis Ovid
728         - Yuval Kogman
729         - Michael Schilli
730         - Slaven Rezic
731         - Lars Thegler
732         - Tony Stubblebine
733         - Tatsuhiko Miyagawa
734         - CPAN Author "CHROMATIC"
735         - Matisse Enzer
736         - Roy Fulbright
737         - Dan Brook
738         - Johnny Lee
739         - Johan Lindstrom
740
741       And to single one person out, thanks go to Randal Schwartz who spent a
742       great number of hours in IRC over a critical 6 month period explaining
743       why Perl is impossibly unparsable and constantly shoving evil and ugly
744       corner cases in my face. He remained a tireless devil's advocate, and
745       without his support this project genuinely could never have been
746       completed.
747
748       So for my schooling in the Deep Magiks, you have my deepest gratitude
749       Randal.
750
752       Copyright 2001 - 2011 Adam Kennedy.
753
754       This program is free software; you can redistribute it and/or modify it
755       under the same terms as Perl itself.
756
757       The full text of the license can be found in the LICENSE file included
758       with this module.
759
760
761
762perl v5.28.0                      2017-06-22                            PPI(3)
Impressum