Letting the User Decide

     

Letting the User Decide

Installing a Perl module distribution is not always as simple as running the build file and testing and installing it. Some modules present the user with configuration options, such as whether to include extra features or to install related utilities. The example tests shown previously have simply skipped certain tests when prerequisite modules are not present. In other cases, it is appropriate to ask the user to decide to run or to skip tests that require network connectivity or tests that may take an exorbitant amount of time to finish.

For example, consider the hypothetical module MD5::Solve , which reverses one-way MD5 checksums at the cost of an incredible amount of time, not to mention computing power and practicality. Performing this sort of task for even a small amount of data is costly, and the test suite for this module must take even more time to run. When installing the module, the user should have the option of skipping the expensive tests.

How do I do that?

ExtUtils::MakeMaker and Module::Build provide prompt( ) functions that prompt and receive input from the user who is installing the module. The functions take one or two arguments: a message to display to the user and a default value. These functions check the environment to make sure a human is indeed sitting at the terminal and, if so, display the message and wait for the user to enter a string. If there is no user present ”in the case of an automated install, for example ”they return the default value.

Using ExtUtils::MakeMaker , the build script for the module Makefile.PL , appears as follows :

 use strict;     use warnings;     use ExtUtils::MakeMaker qw( WriteMakefile prompt );     my %config = (         NAME          => 'MD5::Solve',         AUTHOR        => 'Emily Anne Perlmonger <emmils@example.com>',         VERSION_FROM  => 'lib/MD5/Solve.pm',         ABSTRACT_FROM => 'lib/MD5/Solve.pm',         PREREQ_PM     => { 'Test::More' => 0, },         dist          => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },         clean => { FILES => 'MD5-Solve-*' },     );     my @patterns = qw( t/*.t );     print "=  => Running the extended test suite may take weeks or years! <=  =\n";     my $answer = prompt( 'Do you want to run the extended test suite?', 'no' );     if ( $answer =~ m/^y/i )      {         print "I'm going to run the extended tests.\n";         push @patterns, 't/long/*.t';     }     else      {         print "Skipping extended tests.\n";     }     $config{test} = { TESTS => join ' ', map { glob } @patterns };     WriteMakefile(%config); 

Running the build script generates a Makefile and displays the following output, prompting the user to make a decision:

 $  perl Makefile.PL  =  => Running the extended test suite may take weeks or years! <=  =     Do you want to run the extended test suite? [no]  no  Skipping extended tests.     Checking if your kit is complete...     Looks good     Writing Makefile for MD5::Solve 

What just happened ?

Many Makefile.PL files consist of a single WriteMakefile( ) statement. The previous Makefile.PL has an additional bit of logic to determine which sets of test scripts to run. The test files in t/ always run, but those in t/long/ run only if the user consents.

This file stores all of the options that a typical Makefile.PL provides to WriteMakefile( ) in a hash instead. By default, the program expands the pattern t/*.t into filenames that use glob by using the techniques described in Bundling Tests with Modules," later in this chapter. The program then adds these filenames to %config .

Before modifying %config , however, the file uses the prompt( ) function to ask the user to decide whether to run the lengthy tests. If the user's answer begins with the letter y , the code adds the glob string t/long/*.t to the list of patterns of test files to run as part of the test suite during make test :

 $  make test  cp lib/MD5/Solve.pm blib/lib/MD5/Solve.pm     PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e"         "test_harness(0, 'blib/lib', 'blib/arch')" t/00.load.t t/pod-coverage.t         t/pod.t t/long/alphanumeric.t t/long/digits.t t/long/long-string.t         t/long/longer-string.t t/long/punctuation.t t/long/random.t         t/long/short.t t/long/simple.t     t/00.load...............ok     t/long/alphanumeric.....ok     t/long/digits...........ok     t/long/long-string......ok     t/long/longer-string....ok     t/long/punctuation......ok     t/long/random...........ok     ... 

However, if ExtUtils::MakeMaker decides not to ask for user input or the user hits the Enter key to accept the default value, the return value of prompt( ) will be no . In the previous example, the user entered no explicitly, so the tests in t/long/ will not run:

 $  make test  cp lib/MD5/Solve.pm blib/lib/MD5/Solve.pm     PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e"         "test_harness(0, 'blib/lib', 'blib/arch')" t/00.load.t t/pod-coverage.t         t/pod.t     t/00.load.........ok     t/pod-coverage....ok     t/pod.............ok     All tests successful.     Files=3, Tests=3,  1 wallclock secs ( 1.09 cusr +  0.09 csys =  1.18 CPU) 



Perl Testing. A Developer's Notebook
Perl Testing: A Developers Notebook
ISBN: 0596100922
EAN: 2147483647
Year: 2003
Pages: 107

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net