David Oswald
2012-09-07 21:52:27 UTC
The question has come up on how to make an Inline::CPP script's C++
component available to several scripts without adding the C++ code and
Inline::CPP to each script. And more importantly, how to re-use the
compiled code. This question really is not so different from "How to
I create reusable code with Perl", and the answer is almost always the
same: "Put it in a module." Nevertheless, given the cognitive
overload that one usually experiences when first getting accustomed to
Inline::C/CPP, Perl's API, and all the joys of perlguts, it can be
easy to overlook how all this can translate into a reusable solution.
Inline's documentation explains how to create a distributable module
with Inline::MakeMaker. But sometimes that's overkill, and all the
user needs is a project-specific module that doesn't need to be
universally distributable or installable. I was thinking I might add
the following section to the Inline::CPP POD, but wanted to request
comments before doing so:
=head1 THE MAKING OF A SIMPLE MODULE
The simplest unit of reusable code within the Perl eco-system is a
module. Often when we think of modules we think of the kind that we
download from CPAN. But those should really be classified as
distributions. Let's consider for a moment just a minimal module;
something that may be project specific, and that doesn't need to be
universally distributable by itself.
=head2 Sample Code
To start, we'll create a simple module, and put it in
C<~/project/lib/> as C<MyModule.pm>:
package MyModule;
use Inline CPP => 'DATA';
use parent 'Exporter';
our @EXPORT = 'greet';
# Nothing to see here.
1;
__DATA__
__CPP__
void greet() {
std::cout << "Hello world\n";
}
Now we'll create a script and put it in C<~/project/bin/> as C<myscript.pl>:
use FindBin;
use lib "$FindBin::Bin/../lib";
use MyModule;
greet();
=head2 What happens now?
The first time you run C<myscript.pl>, Inline::CPP will build the C++
code from MyModule.pm, and assuming the build succeeds, it will be
cached so that on future runs there is no need to recompile unless the
C++ code is altered in some way. If MyModule.pm is placed in some
C<lib/</c> path where Perl already looks for modules (possibly
something set up using L<local::lib>, the use of L<FindBin> and the
L<lib> pragma wouldn't even be necessary. And if you want to make
things even more robust, you can add a C<$VERSION> to the module,
specify an explicit build directory and build name, and even follow
the steps outlined in L<Inline> for converting it to a distributable
module. But for simple needs, you're done. Celebrate. Enjoy.
=cut
-------------------------
If anyone has any comments or suggestions, please let me know. In a
day or two I'll push the POD enhancement to github, and it will be
staged for the next release of Inline::CPP v0.42 (no timeframe planned
yet).
Dave
component available to several scripts without adding the C++ code and
Inline::CPP to each script. And more importantly, how to re-use the
compiled code. This question really is not so different from "How to
I create reusable code with Perl", and the answer is almost always the
same: "Put it in a module." Nevertheless, given the cognitive
overload that one usually experiences when first getting accustomed to
Inline::C/CPP, Perl's API, and all the joys of perlguts, it can be
easy to overlook how all this can translate into a reusable solution.
Inline's documentation explains how to create a distributable module
with Inline::MakeMaker. But sometimes that's overkill, and all the
user needs is a project-specific module that doesn't need to be
universally distributable or installable. I was thinking I might add
the following section to the Inline::CPP POD, but wanted to request
comments before doing so:
=head1 THE MAKING OF A SIMPLE MODULE
The simplest unit of reusable code within the Perl eco-system is a
module. Often when we think of modules we think of the kind that we
download from CPAN. But those should really be classified as
distributions. Let's consider for a moment just a minimal module;
something that may be project specific, and that doesn't need to be
universally distributable by itself.
=head2 Sample Code
To start, we'll create a simple module, and put it in
C<~/project/lib/> as C<MyModule.pm>:
package MyModule;
use Inline CPP => 'DATA';
use parent 'Exporter';
our @EXPORT = 'greet';
# Nothing to see here.
1;
__DATA__
__CPP__
void greet() {
std::cout << "Hello world\n";
}
Now we'll create a script and put it in C<~/project/bin/> as C<myscript.pl>:
use FindBin;
use lib "$FindBin::Bin/../lib";
use MyModule;
greet();
=head2 What happens now?
The first time you run C<myscript.pl>, Inline::CPP will build the C++
code from MyModule.pm, and assuming the build succeeds, it will be
cached so that on future runs there is no need to recompile unless the
C++ code is altered in some way. If MyModule.pm is placed in some
C<lib/</c> path where Perl already looks for modules (possibly
something set up using L<local::lib>, the use of L<FindBin> and the
L<lib> pragma wouldn't even be necessary. And if you want to make
things even more robust, you can add a C<$VERSION> to the module,
specify an explicit build directory and build name, and even follow
the steps outlined in L<Inline> for converting it to a distributable
module. But for simple needs, you're done. Celebrate. Enjoy.
=cut
-------------------------
If anyone has any comments or suggestions, please let me know. In a
day or two I'll push the POD enhancement to github, and it will be
staged for the next release of Inline::CPP v0.42 (no timeframe planned
yet).
Dave
--
David Oswald
daoswald-***@public.gmane.org
David Oswald
daoswald-***@public.gmane.org