Finding prerequisites, part II

brian_d_foy on 2002-10-05T04:18:02

MakeMaker is not the only way to install modules. Someday Module::Build will take over and people will forget all about make files. Module::Build works if you only have Perl; if you are installing modules you probably have Perl. On some platforms, you might have to hunt down make or suffer a contentous download and installation.

Module::Build has a couple of advantages over WriteMakefile, but my favorite is that it can tell the difference between modules required for the to-be-installed module to work, and modules necessary for the tests. As Test::More and its friends take over the world, that distinction becomes more important.

Test::Prereq needs to deal with Module::Build if it is going to be any use in the future. Iain Truskett sent me some code to get me going on adding Module::Build support.

The trick is to pretend to be a Module::Build object. WriteMakefile is just a function, so overriding it is not a problem. Replacing Module::Build->new is a bit more tricky. When Test::Prereq requires Build.PL, it needs to completely handle any method calls or the require will fail ("can't call method on blah blah blah").

The new trickery is pretty easy.

sub Module::Build::new
	{
	my $class = shift;
	
	my %hash = @_;
	
	my @requires = sort grep $_ ne 'perl', (
		keys %{ $hash{requires} }, 
		keys %{ $hash{build_requires} },
		);

@Test::Prereq::prereqs = @requires; # intercept further calls to this object return bless {}, __PACKAGE__; }


The last line is the magic; return a "object" in the current namespace. Everything in the Build.PL has to work, as long as I redefine "work", and that's easy. I just make every method a virtual no-op.

sub create_build_script { 1 }


Once I decide to do that, I can just AUTOLOAD every method and do nothing.

I like that Perl allows me do muck around with other packages. I have done that sort of thing for cute hacks, but this is really the first time that it has ever been useful.