1

Background

I am attempting to import a perl module that does not end in .pm with a method similar to this answer:

use lib "/hard/coded/directory"; use scripting;

However, when I attempt to import a module in this way, I get the following error when running perl -c:

Can't locate scripting.pm in @INC (@INC contains: ... ... ... /hard/coded/directory) at name of script line 47.

BEGIN failed--compilation aborted at name of script line 47.

Question

How do I import a perl module outside of @INC that does not have .pm at the end of the file?

Community
  • 1
  • 1
isakbob
  • 1,439
  • 2
  • 17
  • 39
  • The module does not end in`.pm`? What is the name of the file with the module code? Why wouldn't you put the code in a file called `the_module.pm`? – mob Aug 22 '19 at 19:34
  • @mob It is a file I don't have privileges to touch. Yes it had shoddy logic, but it also has a function that I need which is defined inside of it. – isakbob Aug 22 '19 at 19:37
  • It is a file called `the_module`? – mob Aug 22 '19 at 19:44
  • @mob its called scripting. I updated it to be less confusing. – isakbob Aug 22 '19 at 19:47

2 Answers2

2

If the source file does not define new namespaces or classes and you just want to read the function definitions or data from a file, Perl provides the do and require functions.

do "scripting";
require "scripting";

The difference between them is that require will look for the file to evaluate to a true value (it expects the last statement in the file to resolve to a non-zero, non-empty value), and will emit a fatal error if this does not happen. (You will often see naked 1; statements at the end of modules to satisfy this requirement).

If scripting really contains class code and you do need all the functionality that the use function provides, remember that

use Foo::Bar qw(stuff);

is just syntactic sugar for

BEGIN {
    $file = <find Foo/Bar.pm on @INC>;
    require "$file";
    Foo::Bar->import( qw(stuff) )
}

and suggests how you can workaround your inability to use use:

BEGIN {
    require "scripting";
    scripting->import()
}

In theory, the file scripting might define some other package and begin with a line like package Something::Else;. Then you would load the package in this module with

BEGIN {
    require "scripting";
    Something::Else->import();
}
mob
  • 117,087
  • 18
  • 149
  • 283
  • The real difference between `do` and `require` is that **`require` should only be used if the file have a `package` declaration matching the file name** which is obviously not the case here. Also, both `do` and `require` require the file to result in a true value if you want to be able to perform any kind of error checking. – ikegami Aug 22 '19 at 19:54
  • Re "*is just syntactic sugar for*", That's not true. It's literally sugar for `BEGIN { require Foo::Bar; Foo::Bar::->import( qw(stuff) ); }` and it's not quite equivalent to what you posted in a couple of ways. – ikegami Aug 22 '19 at 20:10
2

If the file has a package directive, the file name and the package directive need to match, so simply fix the file name.


If the file doesn't have a package directive, you don't have a module, and you shouldn't use use or require. This can cause problems.

What you have is sometimes called a library, and you should use do.

do('/hard/coded/directory/scripting')
   or die $@ || $!;

(For proper error checking, the file needs to result in a true value.)

That said, you are probably trying to do something really awful. I'm guessing you're either have a configuration file written in Perl or a poorly written module. Perl is not a suitable choice of language for a configuration file, and avoiding namespaces is just bad programming with no benefit.

ikegami
  • 367,544
  • 15
  • 269
  • 518