ExtUtils-PerlPP
view release on metacpan or search on metacpan
Fix defaults, for example installation paths.
=item -
Including or excluding code sections. It is a matter of taste whether one
likes to see
if ($] < 5.003) {
# Thirty lines of code following here
...
} else {
# A single line of code
...
}
when already using Perl 5.005. I don't.
=back
This module is dedicated to simplify such tasks. In short, you can use
it like this:
=head2 Create a new preprocessor
You start with creating an instance of I<ExtUtils::PerlPP> by calling
the I<new> constructor:
my $ppp = ExtUtils::PerlPP->new(%attr);
The constructor accepts a list of attributes, including the following:
=over 8
=item in_fh
The input file, any kind of IO object, for example an instance of
IO::File or IO::Scalar. More general: It can be any object that offers
a I<getline> method.
A scalar value (to be distinguished from an IO::Scalar instance!) will
be interpreted as a file name that the method opens for you.
=item out_fh
The output file; another IO object or any other object that offers a
I<print> method. A scalar value is accepted as output file name.
=item config
A hash ref of preprocessor variables. In other words
$ppp->{'config'}->{'var'} = 1;
is what C<-Dvar=val> is for the C preprocessor. Similarly you can compare
delete $ppp->{'config'};
with C<-Uvar>. See L<"Macro replacements"> below. Unlike C, variables may
be arbitrarily complex, in particular you can use hash or array refs as
values.
Surprisingly you may pass a scalar value again: In that case the file of
the same name evaluated and the result is used as a configuration hash.
In other words
$ppp->{'config'} = "myapp.cfg";
is similar to
$ppp->{'config'} = do "myapp.cfg";
Such config files can easily be created using the I<Data::Dumper> module.
L<Data::Dumper(3)>.
=item no_config_default
If a variable name is used, but no such attribute is present in the
I<config> hash, then by default the variable is looked up in the
C<$Config> from the I<Config> module. This behaviour is suppressed,
if you set I<no_config_default> to a TRUE value. L<Config(3)>.
=item no_makedirs
By default directories are created silently if required. For example,
if you pass a value of C</usr/local/foo/bar> as output file and only
C</usr/local> exists, then the subdirectory C<foo> will be created.
The option I<no_makedirs> suppresses this behaviour.
=back
=head2 Running the preprocessor
This is done by executing
$ppp->parse();
A Perl exception will be thrown in case of errors, thus the complete
use might look like this:
eval { $ppp->parse(); };
if ($@) { print "An error occurred: $@\n" }
=head2 Using the frontend
Most applications won't call the I<new> or I<parse> methods directly,
but rather do a
use ExtUtils::PerlPP;
ppp('infile', 'outfile', 'configfile');
This is equivalent to
my $parser = ExtUtils::PerlPP->new('in_fh' => 'infile',
'out_fh' => 'outfile',
'config' => 'configfile');
$parser->parse();
In order to be easily used within Makefiles, the ppp frontend can
read from @ARGV. That is, you can use the module like this:
perl -MExtUtils::PerlPP -e ppp <infile> <outfile> <configfile>
from the commandline.
=head2 Macro replacements
The primary use of preprocessor variables (aka attributes of
C<$ppp->{'config'}>) is replacing patterns in the stream written to
the output file. With C<$c = $ppp->{'config'}> in mind the typical
patterns and their replacements are:
~~a~~ $c->{'a'}
~~b~~ $c->{'b'}
~~a->b~~ $c->{'a'}->{'b'}
~~a->e~~ $c->{'a'}->{'e'}
~~a->1~~ $c->{'a'}->[1]
~~a->1->b~~ $c->{'a'}->[1]->{'b'}
I hope the idea is obvious. Real world examples might be:
my $config_file = "~~etc_dir~~/configuration";
my $VERSION = "~~version~~";
Preprocessor variables need not be scalar values: If a variable contains a
code ref, then the module will execute
&$var($ppp, $text);
and replace the pattern with the result. C<$text> is the pattern being
replaced, for example, if C<$ppp->{'config'}->{'bar'}> has the value
C<\&foo>, then C<~~bar~~> will be replaced with the result of
foo($ppp, "bar");
Arguments are not yet supported.
=head2 Creating macros
When talking about code refs, we need a possibility to create them.
The best possibility is creating them within the input file, as in
~&foo&~ my($self, $text) = @_; $text x 2; ~&&~
This example is mainly equivalent to
$ppp->{'config'}->{'foo'} = sub {
my($self, $text) = @_; $text x 2;
};
The C<~&var&~> definition must start at the beginning of a line, much
like the C preprocessor. The end pattern ~&&~ may appear at any point,
but the remaining line will be ignored.
=head2 Conditional output
The next application of a preprocessor is conditional output, as in an
#ifdef var
...
#endif
segment. This can be done with
( run in 1.063 second using v1.01-cache-2.11-cpan-39bf76dae61 )