Recently in Installation Category

It has been common practice within the Perl community for ages to ship distributions with a Makefile.PL so that the user will be able to install the packages when he retrieves them, either via the shell which the CPAN/CPANPLUS modules offer or via manual CPAN download.

The Makefile.PL consists of meta-information, which in the case of the distribution HTML::Tagset is:

Of interest are the arguments to WriteMakefile(), because they influence the Makefile written by ExtUtils::MakeMaker after the user has invoked the usual build and install procedure:

% perl Makefile.PL
% make
% make test
# make install

Module::Build, Successor of ExtUtils::MakeMaker?

As Ken Williams grew tired of ExtUtils::MakeMaker and its portability issues, he invented Module::Build, a successor of ExtUtils::MakeMaker. One goal of Module::Build is to run smoothly on most operating systems, because it takes advantage of creating Perl-valid syntax files only and does not rely upon crufty Makefiles, which are often subject to misinterpretation, because so many incompatible flavors of make exist in the wild.

The current maintainer of ExtUtils::MakeMaker, Michael G. Schwern, elaborated about this problem in his talk reachable via "MakeMaker is DOOMED."

Module::Build Distribution "Skeleton"

If you take in consideration the distribution HTML::Tagset again, the rough skeleton suitable for Module::Build having converted the Makefile.PL by Module::Build::Convert into a Build.PL, the output would be:

As you can see, while ExtUtils::MakeMaker prefers uppercased arguments, Module::Build goes by entirely lowercased arguments, which obey the rule of least surprise by being as intuitive as a description can be.

The build and installation procedure for a Module::Build distribution is:

% perl Build.PL
% perl Build
% perl Build test
# perl Build install

Module::Build::Convert's State of Operation

Module::Build::Convert actually does all of the background work and can be safely considered the back end, whereas make2build is the practical front-end utility. Module::Build::Convert currently exposes two kinds of operation: static approach and dynamic execution. The static approach parses the arguments contained within the Makefile.PL'sWriteMakefile() call, whereas dynamic execution runs the Makefile.PL and captures the arguments provided to WriteMakefile().

Module::Build::Convert parses statically by default, because the dynamic execution has the downside that code will be interpreted and the interpreted output will be written to the Build.PL, so you have to conclude that the user of the distribution will end up with predefined values computed on the author's system. This is something to avoid, whenever possible! If the parsing approach fails, perhaps looping endlessly on input, Module::Build::Convert will reinitialize to perform dynamic execution of the Makefile.PL instead.

Module::Build::Convert comes with a rather huge data section containing the argument conversion table, default arguments, sorting order, and begin and end code. If you wish to change this data, consider making a ~/.make2buildrc file by launching make2build with the -rc switch. Do not edit the Data section within Module::Build::Convert directly, unless you are sure you want to submit a patch.

Argument Conversion

On the left-hand side is the MakeMaker's argument name, and on the right-hand side the Module::Build's equivalent.

End Code

make2build Basic Usage

Using make2build is as easy as launching it in the directory of the distribution of which Makefile.PL you wish to convert.

For example:

% make2build

You may also provide the full path to the distribution, assuming, for example, you didn't cd directly into the distribution directory.

% make2build /path/to/HTML-Tagset*

In both cases, the command will convert any found Makefile.PL files and will generate no output because make2build acts quiet by default.

make2build Switches

As make2build aims to be a proper script, it of course, provides both the -h (help screen) and -V (version) switches.

% make2build -h
% make2build -V

In case you end up with a mangled Build.PL written, you can examine the parsing process by launching make2build with the -d switch, enabling the pseudo-interactive debugging mode.

% make2build -d

Should you not like the indentation length or judge it to be too small, increase it via the -l switch followed by an integer.

% make2build -l length

If you don't agree with the sorting order predefined in Module::Build::Convert, you may enforce the native sorting order, which strives to arrange standard arguments with those seen available in the Makefile.PL.

% make2build -n

The argument conversion table, default arguments to add, the sorting order of the arguments, and the begin and end code aren't absolute, either. Change them by invoking make2build with the -rc switch to create a resource configuration file in the home directory of the current user; that is likely ~/.make2build.rc.

% make2build -rc

While make2build is quiet by default, there are two verbosity levels. To enforce verbosity level 1, launch make2build with -v. To enforce verbosity level 2, use -vv.

With -v, the code will warn about Makefile.PL options it does not understand or skips. With -vv, it will accumulate -v output and the entire generated Build.PL.

% make2build -v
% make2build -vv

You may execute the Makefile.PL in first place, but such usage is deprecated because Module::Build::Convert downgrades automatically when needed.

% make2build -x (deprecated)

Swinging with Perl

Phil Crow

Perl does not have a native graphical user interface (GUI) toolkit. So we use all manner of existing GUI tools in front of our Perl applications. Often we use a web browser. We have long had Perl/Tk and other libraries based on C/C++. Now we can also use Java's Swing toolkit with similar ease.

In my sample application, when the user presses a button, Perl evaluates an arithmetic expression from the input text box. The result appears in another text box. I'll show the code for this application a piece at a time with a discussion after each piece. To see the whole thing, look in the examples directory of the Java::Swing distribution.

My evaluation is simple. I retrieve the text from the expression JTextField, eval it, and pass the result to setText on the answer JTextField. Using eval raises possible security concerns, so use it wisely.

sub ending {
$swinger->stop();
}

When the user closes the window, I stop the event loop by calling stop on the Java::Swing instance gained earlier. This kills the program.

With Java::Swing, you can build Swing apps in Perl with some important bits of syntactic sugar. First, you don't need to have separate Java files or inline sections. Second, you can pass named arguments to constructors. Finally, you can easily connect event listeners to Perl callback code.

Scriptify Your Module

Josh McAdams

Recently during an MJD talk at Chicago.pm, I saw a little Perl trick that was so amazingly simple and yet so useful that it was hard to believe that more mongers in the crowd hadn't heard of it. The trick involved taking your module and adding a driver routine to it so the module could run as a script.

To illustrate, start with an example module that contains two utility subroutines that convert weights between pounds and kilograms. The subroutines accept some number and multiplies it by a conversion factor.

Assuming that the real module has a little error checking and POD, this module would serve you just fine. However, what if you decided that we needed to be able to easily do weight conversions from the command line? One option would be to write a Perl script that used WeightConverter. If that seems like too much effort, there is a one-liner that would do conversions.

This would do the trick, but it is a lot to remember and isn't very fun to type. There is a lot of benefit available from saving some form of script, and believe it or not, the module can hold that script. All that you have to do is write some driver subroutine and then call that subroutine if the module is not being used by another script. Here is an example driver for WeightConverter.

This example driver script just loops through the command-line arguments and tries to find instances where the argument contains either a k or p equal to some value. Based on whether or not you are starting with pounds or kilograms, it calls the appropriate subroutine and prints the results.

Now all that is left is to tell the module to run the run subroutine if someone has run the module on its own. This is as easy as adding one line somewhere in the main body of the module.

run unless caller;

All this statement does is execute the run subroutine unless the caller function returns a value. caller will only return true if WeightConverter is being used in another script. Now, this module is usable in other scripts as well as on the command line.

Mocks in Your Test Fixtures

Since writing Test::MockObject,
I've used it in nearly every complex test file I've written. It makes my life
much easier to be able to control only what I need for the current group of
tests.

I wish I'd written Test::MockObject::Extends
earlier than I did; that module allows you to decorate an existing object with
a mockable wrapper. It works just as the wrapped object does, but if you add
any mocked methods, it will work like a regular mock object.

This is very useful when you don't want to go through all of the overhead of
setting up your own mock object but do want to override one or two methods.
(It's almost always the right thing to do instead of using
Test::MockObject..)

Another very useful test module is Test::Class. It
takes more work to understand and to use than Test::More, but
it pays back that investment by allowing you to group, reuse, and organize
tests in the same way you would group, reuse, and organize objects in your
code. Instead of writing your tests procedurally, from the start to the end of
a test file, you organize them into classes.

This is most useful when you've organized your code along similar lines.
If you have a base class with a lot of behavior and a handful of subclasses
that add and override a little bit of behavior, write a
Test::Class-based test for the base class and smaller tests
that inherit from the base test for the subclasses.

Goodbye, duplicate code.

Fixtures

Test::Class encourages you to group related tests into test
methods. This allows you to override and extend those groups of tests in
test subclasses. (Good OO design principles apply here; tests are still
just code, after all.) One of the benefits of grouping tests in this way is
that you can use test fixtures.

A test fixture is another method that runs before every test method. You
can use them to set up the test environment--creating a new object to
test, resetting test data, and generally making sure that tests don't
interfere with each other.

Assuming that there's a test_class() method that returns
the name of the class being tested, this fixture creates a new instance
before every test method and stores it as the object
attribute. The test methods can then fetch this as normal.

Putting Them Together

I recently built some tests for a large system using
Test::Class. Some of the tests had mockable features--they
dealt with file or database errors, for example. I found myself creating a
lot of little Test::MockObject::Extends instances within most
of the tests.

Then inspiration struck. Duplication is bad. Repetition is bad. Factor
it out into one place.

The insight was quick and sudden. If
Test::MockObject::Extends is transparent (and if it isn't,
please file a bug--I'll fix it), I can use it in the test fixture all the
time and then be able to mock whenever I want without doing any setup. I
changed my fixture to:

The rest of my code remained unchanged, except that now I could delete
several identical lines from several test methods.

Do note that, for this to work, you must adhere to good OO design
principles in the code being tested. Don't assume that ref is
always what you think it should be (and use the isa() method
instead).

Sure, this is a one-line trick, but it removed a lot of busy work from
my life and it illustrates two interesting techniques for managing tests.
If you need simpler, more precise mocks, use
Test::MockObject::Extends. If you need better organization and
less duplication in your test files, use Test::Class. Like all
good test modules, they work together almost flawlessly.