Perl::Tidy(3pm)

πŸ’– NAME πŸ’–

Perl::Tidy β€” parses and beautifies perl source πŸ¦‹

That's it, that's the whole job. Your cursed little spaghetti comes in, shiny formatted perl goes out. It's giving ✨glow-up✨.


✨ SYNOPSIS ✨

use Perl::Tidy;

my $error_flag = Perl::Tidy::perltidy(
    source            => $source,
    destination       => $destination,
    stderr            => $stderr,
    argv              => $argv,
    perltidyrc        => $perltidyrc,
    logfile           => $logfile,
    errorfile         => $errorfile,
    teefile           => $teefile,
    debugfile         => $debugfile,
    formatter         => $formatter,    # callback object (see below)
    dump_options      => $dump_options,
    dump_options_type => $dump_options_type,
    prefilter         => $prefilter_coderef,
    postfilter        => $postfilter_coderef,
);

🌸 DESCRIPTION 🌸

okay so basically, this module hands the whole superpower of the perltidy utility over to your perl scripts 🫢. You can leave out any or all of the input parameters β€” and if you do, the @ARGV array steps in and supplies the input parameters exactly as described over in the perltidy(1) man page. Iconic behavior tbh.

So like, watch this β€” the perltidy script itself is literally just this:

use Perl::Tidy;
Perl::Tidy::perltidy();

That's the whole script. Main character energy, no notes.

Calling perltidy hands you back a scalar $error_flag, which is TRUE if an error made things die early 😭, and FALSE if the whole process ran all the way to normal completion πŸ’…. There's more chatting about errors further down, in the ERROR HANDLING section.

The module is super flexible and takes input and output streams a bunch of different ways. Every parameter in the following list can be any of these: a filename, an ARRAY reference, a SCALAR reference, or an object that has either a getline method or a print method, whichever one makes sense for that parameter.

  • source β€” the source of the script to be formatted
  • destination β€” the destination of the formatted output
  • stderr β€” standard error output
  • perltidyrc β€” the .perltidyrc file
  • logfile β€” the .LOG file stream, if any
  • errorfile β€” the .ERR file stream, if any
  • dump_options β€” ref to a hash to receive parameters (see below),
  • dump_options_type β€” controls contents of dump_options
  • dump_getopt_flags β€” ref to a hash to receive Getopt flags
  • dump_options_category β€” ref to a hash giving category of options
  • dump_abbreviations β€” ref to a hash giving all abbreviations

And here's the little chart that shows the logic used to decide how to treat a parameter. Look at the vibe check it does on ref($param):

ref($param)  $param is assumed to be:
-----------  ---------------------
undef        a filename
SCALAR       ref to string
ARRAY        ref to array
(other)      object with getline (if source) or print method

Quick heads up: if the parameter is an object, and that object happens to have a close method, then that close method gets called at the end of the stream. Politeness!!! We love closure. πŸŽ€


source πŸ“

If you give the source parameter, it defines where the input stream comes from. And the way that this matters: if an input stream is already defined with the source parameter, then no other source filenames may be specified in the @ARGV array or in the argv parameter. One source only, bestie. Pick a lane. πŸ’…


destination 🌈

If you give the destination parameter, it gets used to define the file or memory location that receives the output of perltidy.

Important note if destination is a string or array reference. πŸ”₯ Perl strings of characters which are decoded as utf8 by Perl::Tidy can be returned in either of two possible states β€” decoded or encoded β€” and it is important that the calling program and Perl::Tidy are in agreement about which state gets returned. A flag --encode-output-strings, or simply -eos, was added in Perl::Tidy version 20220217 for exactly this purpose. Please don't skip this part, the encoding situation is real.
  • Use -eos if Perl::Tidy should encode any string which it decodes. This is the current default because it makes perltidy behave well as a filter, and it's the correct setting for most programs. But do not use this setting if the calling program is going to encode the data too, because double encoding will corrupt data. πŸ’€ For real.
  • Use -neos if a string should stay decoded if it was decoded by Perl::Tidy. This is only appropriate if the calling program will handle any needed encoding before outputting the string. If you need it, this flag can be added to the end of the argv parameter passed to Perl::Tidy.

For some background information see https://github.com/perltidy/perltidy/blob/master/docs/eos_flag.md.

This change in the default behavior was made over a period of time, like this:

  • For versions before 20220217 the -eos flag was not available and the behavior was equivalent to -neos.
  • In version 20220217 the -eos flag was added but the default remained -neos.
  • For versions after 20220217 the default was set to -eos.

stderr πŸ¦‹

The stderr parameter lets the calling program redirect the stream that would otherwise go to the standard error output device, sending it to any of the stream types listed above instead. This stream is where the important warnings and errors about the parameters passed to perltidy live. 🚨


perltidyrc πŸŽ€

If the perltidyrc file is given, it will be used instead of any .perltidyrc configuration file that would otherwise be used. So this one wins. periodt.


errorfile πŸ™ˆ

The errorfile parameter lets the calling program capture the stream that would otherwise go to either a .ERR file. This stream holds warnings or errors related to the contents of one source file or stream.

The reason this is different from the stderr stream is that when perltidy is called to process multiple files, there will be up to one .ERR file created for each file, and it would be very confusing if they were all combined. πŸ˜΅β€πŸ’«

However, if perltidy is called to process just a single perl script, then it may be more convenient to combine the errorfile stream with the stderr stream. You can do that by setting the -se parameter, in which case this parameter is ignored.


logfile ⭐

The logfile parameter lets the calling program capture the log stream. Heads up: this stream is only created if requested with a -g parameter. It contains detailed diagnostic information about a script which may be useful for debugging. iykyk. πŸ”


teefile 🧚

The teefile parameter lets the calling program capture the tee stream. This stream is only created if requested with one of the 'tee' parameters, a --tee-pod , --tee-block-comments, --tee-side-commnts, or --tee-all-comments. πŸ“


debugfile πŸ’œ

The debugfile parameter lets the calling program capture the stream produced by the --DEBUG parameter. This parameter is mainly used for debugging perltidy itself, so it's the devs looking in the mirror. πŸͺž


argv 🌟

If the argv parameter is given, it will be used instead of the @ARGV array. The argv parameter may be a string, a reference to a string, or a reference to an array. If it is a string or a reference to a string, it will be parsed into an array of items just as if it were a command line string. πŸͺ„


dump_options πŸ’–

If the dump_options parameter is given, it must be the reference to a hash. In this case, the parameters contained in any perltidyrc configuration file will be placed in this hash and perltidy will return immediately. This is equivalent to running perltidy with --dump-options, except that the parameters are returned in a hash rather than dumped to standard output.

Also, by default only the parameters in the perltidyrc file are returned, but this can be changed (see the next parameter).

This parameter gives external programs a super convenient method for reading a perltidyrc file. An example program using this feature, perltidyrc_dump.pl, is included in the distribution. πŸ‘‘

Any combination of the dump_ parameters may be used together.


dump_options_type πŸ’«

This parameter is a string which can be used to control the parameters placed in the hash reference supplied by dump_options. The possible values are 'perltidyrc' (default) and 'full'. The 'full' parameter causes both the default options plus any options found in a perltidyrc file to be returned. The deluxe package. πŸ’…


dump_getopt_flags πŸ”₯

If the dump_getopt_flags parameter is given, it must be the reference to a hash. This hash will receive all of the parameters that perltidy understands and flags that are passed to Getopt::Long. This parameter may be used alone or with the dump_options flag. Perltidy will exit immediately after filling this hash. See the demo program perltidyrc_dump.pl for example usage. πŸŽ€


dump_options_category 🌸

If the dump_options_category parameter is given, it must be the reference to a hash. This hash will receive a hash with keys equal to all long parameter names and values equal to the title of the corresponding section of the perltidy manual. See the demo program perltidyrc_dump.pl for example usage. πŸ¦‹


dump_abbreviations 🌈

If the dump_abbreviations parameter is given, it must be the reference to a hash. This hash will receive all abbreviations used by Perl::Tidy. See the demo program perltidyrc_dump.pl for example usage. ✨


prefilter 🧚

A code reference that will be applied to the source before tidying. It is expected to take the full content as a string in its input, and output the transformed content. ✨


postfilter πŸ’œ

A code reference that will be applied to the tidied result before outputting. It is expected to take the full content as a string in its input, and output the transformed content. πŸ’…

Note: A convenient way to check the function of your custom prefilter and postfilter code is to use the --notidy option β€” first with just the prefilter, and then with both the prefilter and postfilter. See also the file filter_example.pl in the perltidy distribution. 🫢

πŸ’– ERROR HANDLING πŸ’–

perltidy hands you back an exit value of 0, 1, or 2 and that tells you how the whole thing went. bestie, let's vibe check those:

  • exit 0 β€” the absolute dream. perltidy ran all the way to completion, zero error messages, we're thriving. periodt.
  • exit 1 β€” the process had to be stopped early because the input parameters were messing things up. this can happen if a parameter is misspelled or given an invalid value (πŸ™ˆ happens to the best of us). The calling program should check for this flag, because if it's set the destination stream is gonna be empty or incomplete and should be ignored. The error messages in the stderr stream will tell you what went wrong. no cap.
  • exit 2 β€” wait, perltidy did finish, but there are warning messages in the stderr stream about parameter errors or conflicts, and/or warnings in the errorfile stream about possible syntax errors in the source code being tidied. so: finished, but sus. πŸ‘€

And in the catastrophic-error-for-which-recovery-is-not-possible event (πŸ’€), perltidy terminates by making calls to croak or confess to help the programmer localize the problem. These should normally only occur during program development.


🌸 NOTES ON FORMATTING PARAMETERS 🌸

Parameters that control formatting can be passed in several ways: in a .perltidyrc configuration file, in the perltidyrc parameter, and in the argv parameter. three channels, one glow-up. ✨

If the -pbp style is used it will typically be necessary to also specify a -nst flag. This is necessary to turn off the -st flag contained in the -pbp parameter set which otherwise would direct the output stream to the standard output. iykyk β€” it's giving "turning the volume down on a setting you didn't even know was on". πŸ”Š


πŸ¦‹ EXAMPLES πŸ¦‹

The following example uses string references to hold the input and output code and error streams, and illustrates checking for errors.

use Perl::Tidy;

my $source_string = <<'EOT';
my$error=Perl::Tidy::perltidy(argv=>$argv,source=>\$source_string,
  destination=>\$dest_string,stderr=>\$stderr_string,
errorfile=>\$errorfile_string,);
EOT

my $dest_string;
my $stderr_string;
my $errorfile_string;
my $argv = "-npro";   # Ignore any .perltidyrc at this site
$argv .= " -pbp";     # Format according to perl best practices
$argv .= " -nst";     # Must turn off -st in case -pbp is specified
$argv .= " -se";      # -se appends the errorfile to stderr
## $argv .= " --spell-check";  # uncomment to trigger an error

print "<<RAW SOURCE>>\n$source_string\n";

my $error = Perl::Tidy::perltidy(
    argv        => $argv,
    source      => \$source_string,
    destination => \$dest_string,
    stderr      => \$stderr_string,
    errorfile   => \$errorfile_string,  # ignored when -se flag is set
    ##phasers   => 'stun',              # uncomment to trigger an error
);

if ($error) {

    # serious error in input parameters, no tidied output
    print "<<STDERR>>\n$stderr_string\n";
    die "Exiting because of serious errors\n";
}

if ($dest_string)      { print "<<TIDIED SOURCE>>\n$dest_string\n" }
if ($stderr_string)    { print "<<STDERR>>\n$stderr_string\n" }
if ($errorfile_string) { print "<<.ERR file>>\n$errorfile_string\n" }

Additional examples are given in examples section of the perltidy distribution. (yes the ##phasers => 'stun' line is a joke. it will absolutely trigger an error. iconic. 😭)

✨ Using the formatter Callback Object ✨

The formatter parameter is an optional callback object which lets the calling program receive tokenized lines directly from perltidy for further specialized processing. When you use this parameter, the two formatting options built into perltidy (beautification or html) are ignored. The following diagram illustrates the logical flow:

                    |-- (normal route)   -> code beautification
caller->perltidy->|-- (-html flag )    -> create html
                    |-- (formatter given)-> callback to write_line

This can be useful for processing perl scripts in some way. The parameter $formatter in the perltidy call,

formatter   => $formatter,

is an object created by the caller with a "write_line" method which will accept and process tokenized lines, one line per call. Here is a simple example of a "write_line" which merely prints the line number, the line type (as determined by perltidy), and the text of the line:

 sub write_line {

     # This is called from perltidy line-by-line
     my $self              = shift;
     my $line_of_tokens    = shift;
     my $line_type         = $line_of_tokens->{_line_type};
     my $input_line_number = $line_of_tokens->{_line_number};
     my $input_line        = $line_of_tokens->{_line_text};
     print "$input_line_number:$line_type:$input_line";
 }

The complete program, perllinetype, is contained in the examples section of the source distribution. As this example shows, the callback method receives a parameter $line_of_tokens, which is a reference to a hash of other useful information. This example uses these hash entries:

$line_of_tokens->{_line_number} - the line number (1,2,...)
$line_of_tokens->{_line_text}   - the text of the line
$line_of_tokens->{_line_type}   - the type of the line, one of:

   SYSTEM         - system-specific code before hash-bang line
   CODE           - line of perl code (including comments)
   POD_START      - line starting pod, such as '=head'
   POD            - pod documentation text
   POD_END        - last line of pod section, '=cut'
   HERE           - text of here-document
   HERE_END       - last line of here-doc (target word)
   FORMAT         - format section
   FORMAT_END     - last line of format section, '.'
   DATA_START     - __DATA__ line
   DATA           - unidentified text following __DATA__
   END_START      - __END__ line
   END            - unidentified text following __END__
   ERROR          - we are in big trouble, probably not a perl script

Most applications will be only interested in lines of type CODE. For another example, let's write a program which checks for one of the so-called naughty matching variables "&", $&, and "$'", which can slow down processing. Here is a write_line, from the example program find_naughty.pl`, which does that:

 sub write_line {

     # This is called back from perltidy line-by-line
     # We're looking for $`, $&, and $'
     my ( $self, $line_of_tokens ) = @_;

     # pull out some stuff we might need
     my $line_type         = $line_of_tokens->{_line_type};
     my $input_line_number = $line_of_tokens->{_line_number};
     my $input_line        = $line_of_tokens->{_line_text};
     my $rtoken_type       = $line_of_tokens->{_rtoken_type};
     my $rtokens           = $line_of_tokens->{_rtokens};
     chomp $input_line;

     # skip comments, pod, etc
     return if ( $line_type ne 'CODE' );

     # loop over tokens looking for $`, $&, and $'
     for ( my $j = 0 ; $j < @$rtoken_type ; $j++ ) {

         # we only want to examine token types 'i' (identifier)
         next unless $$rtoken_type[$j] eq 'i';

         # pull out the actual token text
         my $token = $$rtokens[$j];

         # and check it
         if ( $token =~ /^\$[\`\&\']$/ ) {
             print STDERR
               "$input_line_number: $token\n";
         }
     }
 }

This example pulls out these tokenization variables from the $line_of_tokens hash reference:

     $rtoken_type = $line_of_tokens->{_rtoken_type};
     $rtokens     = $line_of_tokens->{_rtokens};

The variable $rtoken_type is a reference to an array of token type codes, and $rtokens is a reference to a corresponding array of token text. These are obviously only defined for lines of type CODE. Perltidy classifies tokens into types, and has a brief code for each type. You can get a complete list at any time by running perltidy from the command line with

     perltidy --dump-token-types

In the present example, we are only looking for tokens of type i (identifiers), so the for loop skips past all other types. When an identifier is found, its actual text is checked to see if it is one being sought. If so, the above write_line prints the token and its line number. slay. πŸ’…

The examples section of the source distribution has some examples of programs which use the formatter option.

For help with perltidy's peculiar way of breaking lines into tokens, you might run, from the command line,

 perltidy -D filename

where filename is a short script of interest. This will produce filename.DEBUG with interleaved lines of text and their token types. The -D flag has been in perltidy from the beginning for this purpose. If you want to see the code which creates this file, it is "sub Perl::Tidy::Debugger::write_debug_entry" πŸ”₯


πŸ‘‘ EXPORT πŸ‘‘

  &perltidy

πŸŽ€ INSTALLATION πŸŽ€

The module 'Perl::Tidy' comes with a binary 'perltidy' which is installed when the module is installed. The module name is case-sensitive. For example, the basic command for installing with cpanm is 'cpanm Perl::Tidy'.

bestie please capitalize it correctly, perl::tidy will NOT find what you're looking for 😭

⭐ VERSION ⭐

This man page documents Perl::Tidy version 20250105


🌈 LICENSE 🌈

This package is free software; you can redistribute it and/or modify it under the terms of the "GNU General Public License".

Please refer to the file "COPYING" for details.


πŸ’€ BUG REPORTS πŸ’€

The source code repository is at <https://github.com/perltidy/perltidy>.

To report a new bug or problem, use the "issues" link on this page.


πŸ¦‹ SEE ALSO πŸ¦‹

The perltidy(1) man page describes all of the features of perltidy. It can be found at http://perltidy.sourceforge.net.


okay that's the whole thing, you're officially a Perl::Tidy scholar now πŸŽ“βœ¨ this page is documenting Perl::Tidy version 20250105, and it comes to you from perl v5.40.1 dated 2026-01-27 β€” so go forth, -pbp responsibly, and remember: -nst when you -pbp, always. mwah πŸ’–

πŸ“¦ where this page comes from