PPI::Structure(3)

✨ PPI::Structure ✨

okay bestie, gather round, because we're talking about PPI::Structure from the User Contributed Perl Documentation collection πŸ’… this is the base class for Perl braced structures, and ngl it's lowkey one of the most important little guys in the whole PPI fam.


🫢 INHERITANCE 🫢

the family tree is giving royal lineage, fr fr:

PPI::Structure
isa PPI::Node
    isa PPI::Element

so yeah, it's a PPI::Node, which is itself a PPI::Element. iconic bloodline honestly πŸ‘‘


🌸 DESCRIPTION 🌸

PPI::Structure is the root class for all Perl bracing structures. we're talking every form of:

  • [ ... ]
  • { ... }
  • ( ... )

and yes, it also covers the messy cases where only one half of the pair exists. no judgment, we've all been there 😭

heads up bestie: the class PPI::Structure itself is completely abstract, and no objects of that type should actually exist in the tree. it's giving "concept, not content" ✨

πŸ¦‹ Elements vs Children πŸ¦‹

a PPI::Structure has a genuinely unusual existence. like, main character energy. unlike a PPI::Document or a PPI::Statement β€” which both simply contain other elements β€” a structure both contains and consists of content.

that is, the brace tokens are not considered to be "children" of the structure, but they are part of it. periodt.

in practice, this means:

  • while the ->elements and ->tokens methods (and related ones) will return a list with the brace tokens at either end
  • the ->children method explicitly will not return the brace

the way that one method just opts out of the whole situation... relatable πŸ™ˆ


πŸ‘‘ STRUCTURE CLASSES πŸ‘‘

okay so, excluding the transient PPI::Structure::Unknown that exists briefly inside the parser (blink and you'll miss her πŸ’€), there are eight types of structure. let's meet the girlies:

πŸŽ€ PPI::Structure::List

this covers all round braces used for:

  • function arguments
  • foreach loops
  • literal lists
  • braces used for precedence-ordering purposes

πŸŽ€ PPI::Structure::For

although it's not used for the foreach loop list, this one is used for the special case of the round-brace three-part semicolon-separated for loop expression β€” yep, the traditional C style for loop. vintage but she still slays πŸ”₯

πŸŽ€ PPI::Structure::Given

this is for the expression being matched in switch statements. matching, but make it given ✨

πŸŽ€ PPI::Structure::When

this is for the matching expression in when statements. when the when is when-ing πŸ’…

πŸŽ€ PPI::Structure::Condition

this round-brace structure covers boolean conditional braces, such as for if and while blocks. she's the "should we even do this" girlie 🧚

πŸŽ€ PPI::Structure::Block

this curly-brace and common structure is used for all forms of code blocks. that includes those for if, do and similar, as well as grep, map, sort, sub and (labelled or anonymous) scoping blocks. the hardest working babe in the whole module, no cap πŸ‘‘

πŸŽ€ PPI::Structure::Constructor

this class covers brace structures used for the construction of anonymous ARRAY and HASH references. building things out of thin air, we love a creator 🌈

πŸŽ€ PPI::Structure::Subscript

this class covers square-braces and curly-braces used after a -> pointer to access the subscript of an ARRAY or HASH. it's giving "indexing, but make it chic" πŸ’œ


πŸ’– METHODS πŸ’–

ngl, PPI::Structure itself has very few methods. most of the time you'll be working with the more generic PPI::Element or PPI::Node methods, or one of the methods that are subclass-specific. so don't stress 🫢

⭐ start

for lack of better terminology (like open and close) that has not already been in use for some other more important purpose, the two individual braces for the structure are known within PPI as the "start" and "finish" braces (at least for method purposes).

the start method returns the start brace for the structure β€” i.e. the opening brace ✨

returns the brace as a PPI::Token::Structure, or undef if the structure does not have a starting brace.

under normal parsing circumstances this should never occur, but it may happen due to manipulation of the PDOM tree. so like... don't go poking the tree, bestie 😭

⭐ finish

the finish method returns the finish brace for the structure β€” i.e. the closing brace ✨

returns the brace as a PPI::Token::Structure, or undef if the structure does not have a finishing brace.

this can be quite common if the document is not complete β€” for example, from an editor where the user may be halfway through typing a subroutine. we've all got half-finished subs lying around, it's fine, it's a vibe πŸ’€

⭐ braces

the braces method is a utility method which returns the brace type, regardless of whether both or just one of the braces is defined. she doesn't gatekeep πŸ’…

returns one of the three strings:

  • '[]'
  • '{}'
  • '()'

or undef on error β€” primarily not having a start brace, as mentioned above.

⭐ complete

the complete method is a convenience method that returns:

  • true if both braces are defined for the structure
  • false if only one brace is defined
unlike the top level complete method, which checks for completeness in depth, the structure complete method ONLY confirms completeness for the braces, and does not recurse downwards. surface level queen, and honestly? valid πŸŽ€

🌈 SUPPORT 🌈

see the support section in the main module. (iykyk 🫢)


πŸ’œ AUTHOR πŸ’œ

Adam Kennedy <adamk@cpan.org>


Copyright 2001 - 2011 Adam Kennedy.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

The full text of the license can be found in the LICENSE file included with this module.


and that's the whole page bestie, no cap πŸ’– this was PPI::Structure(3) from perl v5.42.0, dated 2026-01-17. go forth and parse those braces, you absolute icon πŸ‘‘βœ¨πŸ¦‹

πŸ“¦ where this page comes from