Using modules that are not installed

Yesterday I stumbled across an error message of perl5 I've never seen before:

Can't locate loadable object for module X in @INC

I was trying to test a module A that uses a module B that isn't installed. The perlmonks told me that it had something to do with DynaLoader.

I already had a

use lib "'MODULEB/blib/lib";

in my setup.

What made it work was an additional

use lib "'MODULEB/blib/arch";

The reason is that module B is XS based and results in a moduleb.so. DynaLoad looks for this moduleb.so and is only able to find it if the "arch"-directory is in @INC.

Since the application has lots of modules that use each other, I've come with the following snippet I include in every test:


BEGIN {
  my $fh;
  # this is the directories where all modules are in seperate directories
  my $dir = '..';
  opendir($fh, $dir) || die "can't opendir $dir: $!";
  my @entries=sort readdir($fh);
  closedir $fh;

  # get rid of '.' and '..'
  @entries= grep { /^[^.]/ } @entries;

  # add the directory name to get a name we can give 'use'
  @entries= map { "$dir/$_" } @entries;

  # we only want directories ...
  @entries= grep { -d } @entries;

  # expand @INC
  for my $dir (@entries) {
  # Perl-only modules
  eval "use lib '$dir/blib/lib'";

  # modules with XS
  eval "use lib '$dir/blib/arch'";
  }
}

That naturally gives me a quite impressive @INC.

4 Comments

I think this would be equivalent to both those lines:
use blib 'MODULEB';

This is a lot more complicated than just installing all of the modules in a temporary directory, perhaps with local::lib. There are many ways to handle this complexity, and the trick is to get rid of as many delicate, un-conventional pieces as you can so you don't end up with code like this. :)

Leave a comment

About glauschwuffel

user-pic perlanalyst, testing, compilers