perlfilter - Source Filters
This article is about a little-known feature of Perl called source filters. Source
filters alter the program text of a module before Perl sees it, much as a C preprocessor
alters the source text of a C program before the compiler sees it. This article tells you more
about what source filters are, how they work, and how to write your own.
The original purpose of source filters was to let you encrypt your program source to
prevent casual piracy. This isn't all they can do, as you'll soon learn. But first, the
basics.
There are three ways to write your own source filter. You can write it in C, use an
external program as a filter, or write the filter in Perl. I won't cover the first two in any
great detail, so I'll get them out of the way first. Writing the filter in Perl is most
convenient, so I'll devote the most space to it.
You now have better understanding of what a source filter is, and you might even have a
possible use for them. If you feel like playing with source filters but need a bit of
inspiration, here are some extra features you could add to the Debug filter.
First, an easy one. Rather than having debugging code that is all-or-nothing, it would be
much more useful to be able to control which specific blocks of debugging code get included.
Try extending the syntax for debug blocks to allow each to be identified. The contents of the DEBUG
environment variable can then be used to control which blocks get included.
Once you can identify individual blocks, try allowing them to be nested. That isn't
difficult either.
Here is an interesting idea that doesn't involve the Debug filter. Currently Perl
subroutines have fairly limited support for formal parameter lists. You can specify the number
of parameters and their type, but you still have to manually take them out of the @_
array yourself. Write a source filter that allows you to have a named parameter list. Such a
filter would turn this:
sub MySub ($first, $second, @rest) { ... }
|
|
into this:
sub MySub($$@) {
my ($first) = shift ;
my ($second) = shift ;
my (@rest) = @_ ;
...
}
|
|
Finally, if you feel like a real challenge, have a go at writing a full-blown Perl macro
preprocessor as a source filter. Borrow the useful features from the C preprocessor and any
other macro processors you know. The tricky bit will be choosing how much knowledge of Perl's
syntax you want your filter to have.
The Source Filters distribution is available on CPAN, in
CPAN/modules/by-module/Filter
|
|
Starting from Perl 5.8 Filter::Util::Call (the core part of the Source Filters
distribution) is part of the standard Perl distribution. Also included is a friendlier
interface called Filter::Simple, by Damian Conway.
Paul Marquess <Paul.Marquess@btinternet.com>
This article originally appeared in The Perl Journal #11, and is copyright 1998 The Perl
Journal. It appears courtesy of Jon Orwant and The Perl Journal. This document may be
distributed under the same terms as Perl itself.
|