Discussion:
POD addition for Inline::CPP
David Oswald
2012-09-07 21:52:27 UTC
Permalink
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
--
David Oswald
daoswald-***@public.gmane.org
Sisyphus
2012-09-08 00:47:23 UTC
Permalink
----- Original Message -----
From: "David Oswald"
Post by David Oswald
To start, we'll create a simple module, and put it in
package MyModule;
use Inline CPP => 'DATA';
use parent 'Exporter';
# 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
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 you have scripts in *different* directories, each of which uses MyModule,
then I think compilation will occur for the first running of *each* of those
scripts.
This could be avoided by specifying the fully qualified path to a designated
build directory, using the DIRECTORY config option (in MyModule.pm).

Can't think of any other problems with your proposal.

Cheers,
Rob

Loading...