我在使用配置文件中定义的常量时遇到问题.这是我的包裹:
package myPackage;
require "APIconfig.pl";
APIconfig::import(APIconfig);
use constant SERVICE_URL => APIconfig::SERVICE_URL();
Run Code Online (Sandbox Code Playgroud)
配置如下所示:
package APIconfig;
use constant SERVICE_URL => 'http://api.example.org/blah';
1;
Run Code Online (Sandbox Code Playgroud)
运行此代码时,我收到以下错误:
Undefined subroutine &APIconfig::SERVICE_URL called at API.pl line 4.
Run Code Online (Sandbox Code Playgroud)
我不能使用'use'而不是'require',因为这需要将配置文件命名为.pm,并且它在我们网络上的许多服务器上都被称为.pl.如何在不重命名文件的情况下使用包?
'use'和'require'之间有两个不同之处.其中一个会影响您当前的问题,另一个则不会.不幸的是,你正在解决一个没有效果的问题.
不同之处是:
1 /'use'调用import()函数,'require'不调用.
2 /'use'在编译时发生,'require'在运行时发生.
你正在解决'require'没有通过显式调用import来调用import()的事实.这不起作用,因为您的模块不导出任何符号并且没有import()子例程.
你没有解决'use'语句在运行时执行的事实.问题是"使用常量SERVICE_URL => APIconfig :: SERVICE_URL();" 在编译时执行,你的'require'没有运行,所以myPackage对APIconfig一无所知.
(令人讨厌的,hacky)解决方案是将'require'语句放入BEGIN块 - 强制它在编译时执行.您还需要删除对import()的调用,因为这会产生运行时错误(由于缺少子例程).
我以前用来解决的测试文件如下:
$ cat APIconfig.pl
package APIconfig;
use constant SERVICE_URL => 'http://api.example.org/blah';
1;
$ cat api.pl
#!/usr/bin/perl
package myPackage;
BEGIN {
require "APIconfig.pl";
}
# APIconfig::import(APIconfig);
use constant SERVICE_URL => APIconfig::SERVICE_URL();
print SERVICE_URL, "\n";
$ ./api.pl
http://api.example.org/blah
Run Code Online (Sandbox Code Playgroud)
真正的解决方案是将APIconfig重写为真实模块.你提示你知道这一点,但环境问题阻碍你采取这种方法.我强烈建议您尝试解决这些问题并正确处理问题.