Hack #95. Modify Semantics with a Source Filter

Tweak Perl's behavior at the syntactic level.

In addition to adding new syntax [Hack #94], source code filters can change the behavior of existing Perl constructs. For example, a common complaint about Perl is that you cannot indent a heredoc properly. Instead you have to write something messed-up like:

sub usage
{
    if ($::VERBOSE)
    {
        print <<"END_USAGE";
Usage: $0 [options] <infile> <outfile>

Options:
    -z       Zero tolerance on formatting errors
    -o       Output overview only
    -d       Debugging mode
END_USAGE
    }
}

rather than something tidily indented like:

sub usage
{
    if ($::VERBOSE)
    {
        print <<"END_USAGE";
            Usage: $0 [options] <infile> <outfile>

            Options:
                -z       Zero tolerance on formatting errors
                -o       Output overview only
                -d       Debugging mode
            END_USAGE
    }
}

Except, of course, you can have your heredoc and indent it too. You just need to filter out the unacceptable indentation before the code reaches the compiler. This is another job for source filters.

The Hack

Suppose that you could use the starting column of a heredoc's terminator to indicate the left margin of each line of the preceding heredoc content. In other words, what if you could indent every line in the heredoc by the same amount as the final terminator marker? If that were the case, then the previous example would work as expected, printing:

$ ksv -z filename

Usage: ksv [options] <infile> <outfile>

Options:
 -z       Zero tolerance on formatting errors
 -o       Output overview only
 -d       Debugging mode

with the start of ...

Get Perl Hacks now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.