Blame README

Packit 72a6dc
NAME
Packit 72a6dc
    Filter::Simple - Simplified source filtering
Packit 72a6dc
Packit 72a6dc
SYNOPSIS
Packit 72a6dc
     # in MyFilter.pm:
Packit 72a6dc
Packit 72a6dc
         package MyFilter;
Packit 72a6dc
Packit 72a6dc
         use Filter::Simple;
Packit 72a6dc
Packit 72a6dc
         FILTER { ... };
Packit 72a6dc
Packit 72a6dc
         # or just:
Packit 72a6dc
         #
Packit 72a6dc
         # use Filter::Simple sub { ... };
Packit 72a6dc
Packit 72a6dc
     # in user's code:
Packit 72a6dc
Packit 72a6dc
         use MyFilter;
Packit 72a6dc
Packit 72a6dc
         # this code is filtered
Packit 72a6dc
Packit 72a6dc
         no MyFilter;
Packit 72a6dc
Packit 72a6dc
         # this code is not
Packit 72a6dc
Packit 72a6dc
DESCRIPTION
Packit 72a6dc
  The Problem
Packit 72a6dc
    Source filtering is an immensely powerful feature of recent versions of
Packit 72a6dc
    Perl. It allows one to extend the language itself (e.g. the Switch
Packit 72a6dc
    module), to simplify the language (e.g. Language::Pythonesque), or to
Packit 72a6dc
    completely recast the language (e.g. Lingua::Romana::Perligata).
Packit 72a6dc
    Effectively, it allows one to use the full power of Perl as its own,
Packit 72a6dc
    recursively applied, macro language.
Packit 72a6dc
Packit 72a6dc
    The excellent Filter::Util::Call module (by Paul Marquess) provides a
Packit 72a6dc
    usable Perl interface to source filtering, but it is often too powerful
Packit 72a6dc
    and not nearly as simple as it could be.
Packit 72a6dc
Packit 72a6dc
    To use the module it is necessary to do the following:
Packit 72a6dc
Packit 72a6dc
    1.  Download, build, and install the Filter::Util::Call module. (If you
Packit 72a6dc
        have Perl 5.7.1 or later, this is already done for you.)
Packit 72a6dc
Packit 72a6dc
    2.  Set up a module that does a "use Filter::Util::Call".
Packit 72a6dc
Packit 72a6dc
    3.  Within that module, create an "import" subroutine.
Packit 72a6dc
Packit 72a6dc
    4.  Within the "import" subroutine do a call to "filter_add", passing it
Packit 72a6dc
        either a subroutine reference.
Packit 72a6dc
Packit 72a6dc
    5.  Within the subroutine reference, call "filter_read" or
Packit 72a6dc
        "filter_read_exact" to "prime" $_ with source code data from the
Packit 72a6dc
        source file that will "use" your module. Check the status value
Packit 72a6dc
        returned to see if any source code was actually read in.
Packit 72a6dc
Packit 72a6dc
    6.  Process the contents of $_ to change the source code in the desired
Packit 72a6dc
        manner.
Packit 72a6dc
Packit 72a6dc
    7.  Return the status value.
Packit 72a6dc
Packit 72a6dc
    8.  If the act of unimporting your module (via a "no") should cause
Packit 72a6dc
        source code filtering to cease, create an "unimport" subroutine, and
Packit 72a6dc
        have it call "filter_del". Make sure that the call to "filter_read"
Packit 72a6dc
        or "filter_read_exact" in step 5 will not accidentally read past the
Packit 72a6dc
        "no". Effectively this limits source code filters to line-by-line
Packit 72a6dc
        operation, unless the "import" subroutine does some fancy
Packit 72a6dc
        pre-pre-parsing of the source code it's filtering.
Packit 72a6dc
Packit 72a6dc
    For example, here is a minimal source code filter in a module named
Packit 72a6dc
    BANG.pm. It simply converts every occurrence of the sequence
Packit 72a6dc
    "BANG\s+BANG" to the sequence "die 'BANG' if $BANG" in any piece of code
Packit 72a6dc
    following a "use BANG;" statement (until the next "no BANG;" statement,
Packit 72a6dc
    if any):
Packit 72a6dc
Packit 72a6dc
        package BANG;
Packit 72a6dc
Packit 72a6dc
        use Filter::Util::Call ;
Packit 72a6dc
Packit 72a6dc
        sub import {
Packit 72a6dc
            filter_add( sub {
Packit 72a6dc
            my $caller = caller;
Packit 72a6dc
            my ($status, $no_seen, $data);
Packit 72a6dc
            while ($status = filter_read()) {
Packit 72a6dc
                if (/^\s*no\s+$caller\s*;\s*?$/) {
Packit 72a6dc
                    $no_seen=1;
Packit 72a6dc
                    last;
Packit 72a6dc
                }
Packit 72a6dc
                $data .= $_;
Packit 72a6dc
                $_ = "";
Packit 72a6dc
            }
Packit 72a6dc
            $_ = $data;
Packit 72a6dc
            s/BANG\s+BANG/die 'BANG' if \$BANG/g
Packit 72a6dc
                unless $status < 0;
Packit 72a6dc
            $_ .= "no $class;\n" if $no_seen;
Packit 72a6dc
            return 1;
Packit 72a6dc
            })
Packit 72a6dc
        }
Packit 72a6dc
Packit 72a6dc
        sub unimport {
Packit 72a6dc
            filter_del();
Packit 72a6dc
        }
Packit 72a6dc
Packit 72a6dc
        1 ;
Packit 72a6dc
Packit 72a6dc
    This level of sophistication puts filtering out of the reach of many
Packit 72a6dc
    programmers.
Packit 72a6dc
Packit 72a6dc
  A Solution
Packit 72a6dc
    The Filter::Simple module provides a simplified interface to
Packit 72a6dc
    Filter::Util::Call; one that is sufficient for most common cases.
Packit 72a6dc
Packit 72a6dc
    Instead of the above process, with Filter::Simple the task of setting up
Packit 72a6dc
    a source code filter is reduced to:
Packit 72a6dc
Packit 72a6dc
    1.  Download and install the Filter::Simple module. (If you have Perl
Packit 72a6dc
        5.7.1 or later, this is already done for you.)
Packit 72a6dc
Packit 72a6dc
    2.  Set up a module that does a "use Filter::Simple" and then calls
Packit 72a6dc
        "FILTER { ... }".
Packit 72a6dc
Packit 72a6dc
    3.  Within the anonymous subroutine or block that is passed to "FILTER",
Packit 72a6dc
        process the contents of $_ to change the source code in the desired
Packit 72a6dc
        manner.
Packit 72a6dc
Packit 72a6dc
    In other words, the previous example, would become:
Packit 72a6dc
Packit 72a6dc
        package BANG;
Packit 72a6dc
        use Filter::Simple;
Packit 72a6dc
Packit 72a6dc
        FILTER {
Packit 72a6dc
            s/BANG\s+BANG/die 'BANG' if \$BANG/g;
Packit 72a6dc
        };
Packit 72a6dc
Packit 72a6dc
        1 ;
Packit 72a6dc
Packit 72a6dc
    Note that the source code is passed as a single string, so any regex
Packit 72a6dc
    that uses "^" or "$" to detect line boundaries will need the "/m" flag.
Packit 72a6dc
Packit 72a6dc
  Disabling or changing <no> behaviour
Packit 72a6dc
    By default, the installed filter only filters up to a line consisting of
Packit 72a6dc
    one of the three standard source "terminators":
Packit 72a6dc
Packit 72a6dc
        no ModuleName;  # optional comment
Packit 72a6dc
Packit 72a6dc
    or:
Packit 72a6dc
Packit 72a6dc
        __END__
Packit 72a6dc
Packit 72a6dc
    or:
Packit 72a6dc
Packit 72a6dc
        __DATA__
Packit 72a6dc
Packit 72a6dc
    but this can be altered by passing a second argument to "use
Packit 72a6dc
    Filter::Simple" or "FILTER" (just remember: there's *no* comma after the
Packit 72a6dc
    initial block when you use "FILTER").
Packit 72a6dc
Packit 72a6dc
    That second argument may be either a "qr"'d regular expression (which is
Packit 72a6dc
    then used to match the terminator line), or a defined false value (which
Packit 72a6dc
    indicates that no terminator line should be looked for), or a reference
Packit 72a6dc
    to a hash (in which case the terminator is the value associated with the
Packit 72a6dc
    key 'terminator'.
Packit 72a6dc
Packit 72a6dc
    For example, to cause the previous filter to filter only up to a line of
Packit 72a6dc
    the form:
Packit 72a6dc
Packit 72a6dc
        GNAB esu;
Packit 72a6dc
Packit 72a6dc
    you would write:
Packit 72a6dc
Packit 72a6dc
        package BANG;
Packit 72a6dc
        use Filter::Simple;
Packit 72a6dc
Packit 72a6dc
        FILTER {
Packit 72a6dc
            s/BANG\s+BANG/die 'BANG' if \$BANG/g;
Packit 72a6dc
        }
Packit 72a6dc
        qr/^\s*GNAB\s+esu\s*;\s*?$/;
Packit 72a6dc
Packit 72a6dc
    or:
Packit 72a6dc
Packit 72a6dc
        FILTER {
Packit 72a6dc
            s/BANG\s+BANG/die 'BANG' if \$BANG/g;
Packit 72a6dc
        }
Packit 72a6dc
        { terminator => qr/^\s*GNAB\s+esu\s*;\s*?$/ };
Packit 72a6dc
Packit 72a6dc
    and to prevent the filter's being turned off in any way:
Packit 72a6dc
Packit 72a6dc
        package BANG;
Packit 72a6dc
        use Filter::Simple;
Packit 72a6dc
Packit 72a6dc
        FILTER {
Packit 72a6dc
            s/BANG\s+BANG/die 'BANG' if \$BANG/g;
Packit 72a6dc
        }
Packit 72a6dc
        "";    # or: 0
Packit 72a6dc
Packit 72a6dc
    or:
Packit 72a6dc
Packit 72a6dc
        FILTER {
Packit 72a6dc
            s/BANG\s+BANG/die 'BANG' if \$BANG/g;
Packit 72a6dc
        }
Packit 72a6dc
        { terminator => "" };
Packit 72a6dc
Packit 72a6dc
    Note that, no matter what you set the terminator pattern to, the actual
Packit 72a6dc
    terminator itself *must* be contained on a single source line.
Packit 72a6dc
Packit 72a6dc
  All-in-one interface
Packit 72a6dc
    Separating the loading of Filter::Simple:
Packit 72a6dc
Packit 72a6dc
        use Filter::Simple;
Packit 72a6dc
Packit 72a6dc
    from the setting up of the filtering:
Packit 72a6dc
Packit 72a6dc
        FILTER { ... };
Packit 72a6dc
Packit 72a6dc
    is useful because it allows other code (typically parser support code or
Packit 72a6dc
    caching variables) to be defined before the filter is invoked. However,
Packit 72a6dc
    there is often no need for such a separation.
Packit 72a6dc
Packit 72a6dc
    In those cases, it is easier to just append the filtering subroutine and
Packit 72a6dc
    any terminator specification directly to the "use" statement that loads
Packit 72a6dc
    Filter::Simple, like so:
Packit 72a6dc
Packit 72a6dc
        use Filter::Simple sub {
Packit 72a6dc
            s/BANG\s+BANG/die 'BANG' if \$BANG/g;
Packit 72a6dc
        };
Packit 72a6dc
Packit 72a6dc
    This is exactly the same as:
Packit 72a6dc
Packit 72a6dc
        use Filter::Simple;
Packit 72a6dc
        BEGIN {
Packit 72a6dc
            Filter::Simple::FILTER {
Packit 72a6dc
                s/BANG\s+BANG/die 'BANG' if \$BANG/g;
Packit 72a6dc
            };
Packit 72a6dc
        }
Packit 72a6dc
Packit 72a6dc
    except that the "FILTER" subroutine is not exported by Filter::Simple.
Packit 72a6dc
Packit 72a6dc
  Filtering only specific components of source code
Packit 72a6dc
    One of the problems with a filter like:
Packit 72a6dc
Packit 72a6dc
        use Filter::Simple;
Packit 72a6dc
Packit 72a6dc
        FILTER { s/BANG\s+BANG/die 'BANG' if \$BANG/g };
Packit 72a6dc
Packit 72a6dc
    is that it indiscriminately applies the specified transformation to the
Packit 72a6dc
    entire text of your source program. So something like:
Packit 72a6dc
Packit 72a6dc
        warn 'BANG BANG, YOU'RE DEAD';
Packit 72a6dc
        BANG BANG;
Packit 72a6dc
Packit 72a6dc
    will become:
Packit 72a6dc
Packit 72a6dc
        warn 'die 'BANG' if $BANG, YOU'RE DEAD';
Packit 72a6dc
        die 'BANG' if $BANG;
Packit 72a6dc
Packit 72a6dc
    It is very common when filtering source to only want to apply the filter
Packit 72a6dc
    to the non-character-string parts of the code, or alternatively to
Packit 72a6dc
    *only* the character strings.
Packit 72a6dc
Packit 72a6dc
    Filter::Simple supports this type of filtering by automatically
Packit 72a6dc
    exporting the "FILTER_ONLY" subroutine.
Packit 72a6dc
Packit 72a6dc
    "FILTER_ONLY" takes a sequence of specifiers that install separate (and
Packit 72a6dc
    possibly multiple) filters that act on only parts of the source code.
Packit 72a6dc
    For example:
Packit 72a6dc
Packit 72a6dc
        use Filter::Simple;
Packit 72a6dc
Packit 72a6dc
        FILTER_ONLY
Packit 72a6dc
            code      => sub { s/BANG\s+BANG/die 'BANG' if \$BANG/g },
Packit 72a6dc
            quotelike => sub { s/BANG\s+BANG/CHITTY CHITTY/g };
Packit 72a6dc
Packit 72a6dc
    The "code" subroutine will only be used to filter parts of the source
Packit 72a6dc
    code that are not quotelikes, POD, or "__DATA__". The "quotelike"
Packit 72a6dc
    subroutine only filters Perl quotelikes (including here documents).
Packit 72a6dc
Packit 72a6dc
    The full list of alternatives is:
Packit 72a6dc
Packit 72a6dc
    "code"
Packit 72a6dc
        Filters only those sections of the source code that are not
Packit 72a6dc
        quotelikes, POD, or "__DATA__".
Packit 72a6dc
Packit 72a6dc
    "code_no_comments"
Packit 72a6dc
        Filters only those sections of the source code that are not
Packit 72a6dc
        quotelikes, POD, comments, or "__DATA__".
Packit 72a6dc
Packit 72a6dc
    "executable"
Packit 72a6dc
        Filters only those sections of the source code that are not POD or
Packit 72a6dc
        "__DATA__".
Packit 72a6dc
Packit 72a6dc
    "executable_no_comments"
Packit 72a6dc
        Filters only those sections of the source code that are not POD,
Packit 72a6dc
        comments, or "__DATA__".
Packit 72a6dc
Packit 72a6dc
    "quotelike"
Packit 72a6dc
        Filters only Perl quotelikes (as interpreted by
Packit 72a6dc
        &Text::Balanced::extract_quotelike).
Packit 72a6dc
Packit 72a6dc
    "string"
Packit 72a6dc
        Filters only the string literal parts of a Perl quotelike (i.e. the
Packit 72a6dc
        contents of a string literal, either half of a "tr///", the second
Packit 72a6dc
        half of an "s///").
Packit 72a6dc
Packit 72a6dc
    "regex"
Packit 72a6dc
        Filters only the pattern literal parts of a Perl quotelike (i.e. the
Packit 72a6dc
        contents of a "qr//" or an "m//", the first half of an "s///").
Packit 72a6dc
Packit 72a6dc
    "all"
Packit 72a6dc
        Filters everything. Identical in effect to "FILTER".
Packit 72a6dc
Packit 72a6dc
    Except for "FILTER_ONLY code => sub {...}", each of the component
Packit 72a6dc
    filters is called repeatedly, once for each component found in the
Packit 72a6dc
    source code.
Packit 72a6dc
Packit 72a6dc
    Note that you can also apply two or more of the same type of filter in a
Packit 72a6dc
    single "FILTER_ONLY". For example, here's a simple macro-preprocessor
Packit 72a6dc
    that is only applied within regexes, with a final debugging pass that
Packit 72a6dc
    prints the resulting source code:
Packit 72a6dc
Packit 72a6dc
        use Regexp::Common;
Packit 72a6dc
        FILTER_ONLY
Packit 72a6dc
            regex => sub { s/!\[/[^/g },
Packit 72a6dc
            regex => sub { s/%d/$RE{num}{int}/g },
Packit 72a6dc
            regex => sub { s/%f/$RE{num}{real}/g },
Packit 72a6dc
            all   => sub { print if $::DEBUG };
Packit 72a6dc
Packit 72a6dc
  Filtering only the code parts of source code
Packit 72a6dc
    Most source code ceases to be grammatically correct when it is broken up
Packit 72a6dc
    into the pieces between string literals and regexes. So the 'code' and
Packit 72a6dc
    'code_no_comments' component filter behave slightly differently from the
Packit 72a6dc
    other partial filters described in the previous section.
Packit 72a6dc
Packit 72a6dc
    Rather than calling the specified processor on each individual piece of
Packit 72a6dc
    code (i.e. on the bits between quotelikes), the 'code...' partial
Packit 72a6dc
    filters operate on the entire source code, but with the quotelike bits
Packit 72a6dc
    (and, in the case of 'code_no_comments', the comments) "blanked out".
Packit 72a6dc
Packit 72a6dc
    That is, a 'code...' filter *replaces* each quoted string, quotelike,
Packit 72a6dc
    regex, POD, and __DATA__ section with a placeholder. The delimiters of
Packit 72a6dc
    this placeholder are the contents of the $; variable at the time the
Packit 72a6dc
    filter is applied (normally "\034"). The remaining four bytes are a
Packit 72a6dc
    unique identifier for the component being replaced.
Packit 72a6dc
Packit 72a6dc
    This approach makes it comparatively easy to write code preprocessors
Packit 72a6dc
    without worrying about the form or contents of strings, regexes, etc.
Packit 72a6dc
Packit 72a6dc
    For convenience, during a 'code...' filtering operation, Filter::Simple
Packit 72a6dc
    provides a package variable ($Filter::Simple::placeholder) that contains
Packit 72a6dc
    a pre-compiled regex that matches any placeholder...and captures the
Packit 72a6dc
    identifier within the placeholder. Placeholders can be moved and
Packit 72a6dc
    re-ordered within the source code as needed.
Packit 72a6dc
Packit 72a6dc
    In addition, a second package variable (@Filter::Simple::components)
Packit 72a6dc
    contains a list of the various pieces of $_, as they were originally
Packit 72a6dc
    split up to allow placeholders to be inserted.
Packit 72a6dc
Packit 72a6dc
    Once the filtering has been applied, the original strings, regexes, POD,
Packit 72a6dc
    etc. are re-inserted into the code, by replacing each placeholder with
Packit 72a6dc
    the corresponding original component (from @components). Note that this
Packit 72a6dc
    means that the @components variable must be treated with extreme care
Packit 72a6dc
    within the filter. The @components array stores the "back- translations"
Packit 72a6dc
    of each placeholder inserted into $_, as well as the interstitial source
Packit 72a6dc
    code between placeholders. If the placeholder backtranslations are
Packit 72a6dc
    altered in @components, they will be similarly changed when the
Packit 72a6dc
    placeholders are removed from $_ after the filter is complete.
Packit 72a6dc
Packit 72a6dc
    For example, the following filter detects concatenated pairs of
Packit 72a6dc
    strings/quotelikes and reverses the order in which they are
Packit 72a6dc
    concatenated:
Packit 72a6dc
Packit 72a6dc
        package DemoRevCat;
Packit 72a6dc
        use Filter::Simple;
Packit 72a6dc
Packit 72a6dc
        FILTER_ONLY code => sub {
Packit 72a6dc
            my $ph = $Filter::Simple::placeholder;
Packit 72a6dc
            s{ ($ph) \s* [.] \s* ($ph) }{ $2.$1 }gx
Packit 72a6dc
        };
Packit 72a6dc
Packit 72a6dc
    Thus, the following code:
Packit 72a6dc
Packit 72a6dc
        use DemoRevCat;
Packit 72a6dc
Packit 72a6dc
        my $str = "abc" . q(def);
Packit 72a6dc
Packit 72a6dc
        print "$str\n";
Packit 72a6dc
Packit 72a6dc
    would become:
Packit 72a6dc
Packit 72a6dc
        my $str = q(def)."abc";
Packit 72a6dc
Packit 72a6dc
        print "$str\n";
Packit 72a6dc
Packit 72a6dc
    and hence print:
Packit 72a6dc
Packit 72a6dc
        defabc
Packit 72a6dc
Packit 72a6dc
  Using Filter::Simple with an explicit "import" subroutine
Packit 72a6dc
    Filter::Simple generates a special "import" subroutine for your module
Packit 72a6dc
    (see "How it works") which would normally replace any "import"
Packit 72a6dc
    subroutine you might have explicitly declared.
Packit 72a6dc
Packit 72a6dc
    However, Filter::Simple is smart enough to notice your existing "import"
Packit 72a6dc
    and Do The Right Thing with it. That is, if you explicitly define an
Packit 72a6dc
    "import" subroutine in a package that's using Filter::Simple, that
Packit 72a6dc
    "import" subroutine will still be invoked immediately after any filter
Packit 72a6dc
    you install.
Packit 72a6dc
Packit 72a6dc
    The only thing you have to remember is that the "import" subroutine
Packit 72a6dc
    *must* be declared *before* the filter is installed. If you use "FILTER"
Packit 72a6dc
    to install the filter:
Packit 72a6dc
Packit 72a6dc
        package Filter::TurnItUpTo11;
Packit 72a6dc
Packit 72a6dc
        use Filter::Simple;
Packit 72a6dc
Packit 72a6dc
        FILTER { s/(\w+)/\U$1/ };
Packit 72a6dc
Packit 72a6dc
    that will almost never be a problem, but if you install a filtering
Packit 72a6dc
    subroutine by passing it directly to the "use Filter::Simple" statement:
Packit 72a6dc
Packit 72a6dc
        package Filter::TurnItUpTo11;
Packit 72a6dc
Packit 72a6dc
        use Filter::Simple sub{ s/(\w+)/\U$1/ };
Packit 72a6dc
Packit 72a6dc
    then you must make sure that your "import" subroutine appears before
Packit 72a6dc
    that "use" statement.
Packit 72a6dc
Packit 72a6dc
  Using Filter::Simple and Exporter together
Packit 72a6dc
    Likewise, Filter::Simple is also smart enough to Do The Right Thing if
Packit 72a6dc
    you use Exporter:
Packit 72a6dc
Packit 72a6dc
        package Switch;
Packit 72a6dc
        use base Exporter;
Packit 72a6dc
        use Filter::Simple;
Packit 72a6dc
Packit 72a6dc
        @EXPORT    = qw(switch case);
Packit 72a6dc
        @EXPORT_OK = qw(given  when);
Packit 72a6dc
Packit 72a6dc
        FILTER { $_ = magic_Perl_filter($_) }
Packit 72a6dc
Packit 72a6dc
    Immediately after the filter has been applied to the source,
Packit 72a6dc
    Filter::Simple will pass control to Exporter, so it can do its magic
Packit 72a6dc
    too.
Packit 72a6dc
Packit 72a6dc
    Of course, here too, Filter::Simple has to know you're using Exporter
Packit 72a6dc
    before it applies the filter. That's almost never a problem, but if
Packit 72a6dc
    you're nervous about it, you can guarantee that things will work
Packit 72a6dc
    correctly by ensuring that your "use base Exporter" always precedes your
Packit 72a6dc
    "use Filter::Simple".
Packit 72a6dc
Packit 72a6dc
  How it works
Packit 72a6dc
    The Filter::Simple module exports into the package that calls "FILTER"
Packit 72a6dc
    (or "use"s it directly) -- such as package "BANG" in the above example
Packit 72a6dc
    -- two automagically constructed subroutines -- "import" and "unimport"
Packit 72a6dc
    -- which take care of all the nasty details.
Packit 72a6dc
Packit 72a6dc
    In addition, the generated "import" subroutine passes its own argument
Packit 72a6dc
    list to the filtering subroutine, so the BANG.pm filter could easily be
Packit 72a6dc
    made parametric:
Packit 72a6dc
Packit 72a6dc
        package BANG;
Packit 72a6dc
Packit 72a6dc
        use Filter::Simple;
Packit 72a6dc
Packit 72a6dc
        FILTER {
Packit 72a6dc
            my ($die_msg, $var_name) = @_;
Packit 72a6dc
            s/BANG\s+BANG/die '$die_msg' if \${$var_name}/g;
Packit 72a6dc
        };
Packit 72a6dc
Packit 72a6dc
        # and in some user code:
Packit 72a6dc
Packit 72a6dc
        use BANG "BOOM", "BAM";  # "BANG BANG" becomes: die 'BOOM' if $BAM
Packit 72a6dc
Packit 72a6dc
    The specified filtering subroutine is called every time a "use BANG" is
Packit 72a6dc
    encountered, and passed all the source code following that call, up to
Packit 72a6dc
    either the next "no BANG;" (or whatever terminator you've set) or the
Packit 72a6dc
    end of the source file, whichever occurs first. By default, any "no
Packit 72a6dc
    BANG;" call must appear by itself on a separate line, or it is ignored.
Packit 72a6dc
Packit 72a6dc
AUTHOR
Packit 72a6dc
    Damian Conway
Packit 72a6dc
Packit 72a6dc
CONTACT
Packit 72a6dc
    Filter::Simple is now maintained by the Perl5-Porters. Please submit bug
Packit 72a6dc
    via the "perlbug" tool that comes with your perl. For usage
Packit 72a6dc
    instructions, read "perldoc perlbug" or possibly "man perlbug". For
Packit 72a6dc
    mostly anything else, please contact <perl5-porters@perl.org>.
Packit 72a6dc
Packit 72a6dc
    Maintainer of the CPAN release is Steffen Mueller <smueller@cpan.org>.
Packit 72a6dc
    Contact him with technical difficulties with respect to the packaging of
Packit 72a6dc
    the CPAN module.
Packit 72a6dc
Packit 72a6dc
    Praise of the module, flowers, and presents still go to the author,
Packit 72a6dc
    Damian Conway <damian@conway.org>.
Packit 72a6dc
Packit 72a6dc
COPYRIGHT AND LICENSE
Packit 72a6dc
        Copyright (c) 2000-2014, Damian Conway. All Rights Reserved.
Packit 72a6dc
        This module is free software. It may be used, redistributed
Packit 72a6dc
        and/or modified under the same terms as Perl itself.
Packit 72a6dc