juettemann
juettemann

Reputation: 323

Perl require fails to find Library in @INC when used in eval


depending on if a certain Module can be loaded, I'd like to decide if it is used:

BEGIN {
  eval {
    require "Bio::EnsEMBL::HDF5";
    $hdf5 = "Bio::EnsEMBL::HDF5";
  };
  if ($@) {
    require "Bio::EnsEMBL::HDF5_mockup";
    $hdf5 = "Bio::EnsEMBL::HDF5_mockup";
  }
}

which results in
Can't locate Bio::EnsEMBL::HDF5_mockup in @INC

However:

use Bio::EnsEMBL::HDF5; 
use Bio::EnsEMBL::HDF5_mockup;

works fine. Also when I switch HDF5 and HDF5_mockup in the BEGIN block, it locates always the one I require first, and fails to find the second one.
Thanks for any pointer.

Upvotes: 1

Views: 404

Answers (2)

ikegami
ikegami

Reputation: 386561

use Bio::EnsEMBL::HDF5; 

almost identical to

BEGIN {
   require Bio::EnsEMBL::HDF5; 
   import Bio::EnsEMBL::HDF5; 
}

and

# Looks for file "Bio::EnsEMBL::HDF5_mockup"
require "Bio::EnsEMBL::HDF5_mockup";

isn't equivalent to

# Looks for file "Bio/EnsEMBL/HDF5_mockup.pm"
require Bio::EnsEMBL::HDF5_mockup;

Upvotes: 4

stevieb
stevieb

Reputation: 9306

This is because when you quote the module when using require, it uses the quoted string as the name of the actual module file. So instead of looking for Bio/EnsEMBL/HDF5.pm, it's searching @INC for a file named Bio::EnsEMBL::HDF5.

Remove the quotes so that the module name is a bareword. Here's an example:

Notice how the module name hasn't been transformed into a file path:

require "Data::Dumper";
Can't locate Data::Dumper in @INC (@INC contains: ...

Now, in this example, I've intentionally mistyped the module name so I could produce the error. Notice how the module has been transformed into an actual file path:

require Data::Dumperx;
Can't locate Data/Dumperx.pm in @INC (you may need to install the Data::Dumperx module)

Upvotes: 9

Related Questions