A bag o' tricks from the Perlmeister
Creating Packages
CPAN accepts tarballs, but to give your users more convenience, you may want to convert the build into a package for the target distributions such as Debian or RPM. If you are not worried about downloading about half of all CPAN modules ever created as dependencies, you can go for Dist::Zilla. For those who prefer a more lightweight approach, I recommend the Ruby tool fpm
[7].
With a reasonably fresh Ruby version, the practical tool installs itself after you type gem install fpm
. It supports numerous options, but to bundle a number of files into a package using one of the supported formats (RPM, Debian, or OS X), you will only need to specify the package type with -t
and point fpm
to the source files under usr
to be included with -s usr
.
In the directory, as the tree
command in Figure 4 shows, the files are stored exactly as they will be placed on the system when installed, that is with the foo
script in usr/bin/foo
and the Perl module Foo.pm
in usr/lib/perl5/site_perl/Foo.pm
. The example specifies Debian as the package format (-t deb
); a .deb
file with the specified version number is thus created.
The tool is fantastically easy to use and shields developers from what are sometimes quite tragic implementations of specific package bundlers, such as rpmbuild
. It can also resolve dependencies on other packages, and it is certainly something that should not be missing from any tool box.
Into the Box
Some new projects may have dependencies on a whole bunch of CPAN modules, for which packages for the end user's distribution may not exist. The time-consuming workaround of opening a CPAN shell and initializing, followed by installing a few dozen modules, which in turn have dependencies on more modules, is something end users shouldn't be burdened with. This is especially true if the target group normally has nothing to do with Perl, and only wants to use a new command-line utility provided by the project.
In these cases, the Carton CPAN module provides invaluable services, because it automatically resolves dependencies stored in a cpanfile
with the following format:
requires 'Log::Log4perl', '1.0'; requires 'Pod::Usage', '0.01';
After onboarding indirectly dependent modules, with carton install, it launches a build process for the whole enchilada in a newly created local
directory. If you then push the results into the directory of the utility discussed in the previous section, fpm
, the tool puts together a package that will work on the target systems regardless of installed modules, thus resulting in a robust release.
Bugs? What Bugs?
All programmers make mistakes, and sometimes you need to put on your crime scene cleaner suit and trudge through the code with Perl's debugger to see where the problem lies. If the problem does not occur at the beginning of the script, but in the middle of a module, you can set a break point in the associated function, step through to the point in question manually, or use my favorite Perl trick: A statement planted at the desired location in the code, like this:
$DB::single = 1;
stops the debugger started with perl -d <script>
and c
at precisely this point. But, sometimes perl
rummages through code even before the actual show in the main program begins. For example, the ORM wrapper Rose::DB creates its data structures while a database module is being loaded with the use My::Data
command.
How can you launch a script that uses this module, so that the debugger stops in My::Data and not just in the first line of the main program? If you add the following line
BEGIN { $DB::single = 1 }
at the beginning of the script, the debugger stops at the first executable line, regardless of whether it's in the main program or somewhere else.
« Previous 1 2 3 4 Next »
Buy this article as PDF
(incl. VAT)