Perl 将所需文件作为use语句导入
我在使用配置文件中定义的常量时遇到问题。 这是我的包裹:Perl 将所需文件作为use语句导入,perl,perl-module,Perl,Perl Module,我在使用配置文件中定义的常量时遇到问题。 这是我的包裹: package myPackage; require "APIconfig.pl"; APIconfig::import(APIconfig); use constant SERVICE_URL => APIconfig::SERVICE_URL(); 配置如下所示: package APIconfig; use constant SERVICE_URL => 'http://api.example.org/blah';
package myPackage;
require "APIconfig.pl";
APIconfig::import(APIconfig);
use constant SERVICE_URL => APIconfig::SERVICE_URL();
配置如下所示:
package APIconfig;
use constant SERVICE_URL => 'http://api.example.org/blah';
1;
运行此代码时,出现以下错误:
Undefined subroutine &APIconfig::SERVICE_URL called at API.pl line 4.
我不能使用“use”而不是“require”,因为这要求配置文件名为.pm,并且在我们网络上的许多服务器上它被称为.pl。
如何在不重命名文件的情况下使用包?这可能不正确-包APIconfig中没有子例程导入。一旦使用完整的包路径访问符号名,就不需要导出/导入 解决方案是在编译时运行require,然后再使用常量。这项工作:
package myPackage;
BEGIN {
require "APIconfig.pl";
}
use constant SERVICE_URL => APIconfig::SERVICE_URL();
这不可能是正确的-包APIconfig中没有子例程导入。一旦使用完整的包路径访问符号名,就不需要导出/导入 解决方案是在编译时运行require,然后再使用常量。这项工作:
package myPackage;
BEGIN {
require "APIconfig.pl";
}
use constant SERVICE_URL => APIconfig::SERVICE_URL();
“使用”和“需要”之间有两个区别。其中一个会影响你当前的问题,另一个不会。不幸的是,您正在处理一个没有效果的问题 区别在于: 1/“use”调用导入函数,“require”不调用 2/“use”发生在编译时,“require”发生在运行时 您正在通过显式调用“require”来解决“require”不调用import的问题。这不起作用,因为您的模块不导出任何符号,也没有导入子例程 您没有绕过“use”语句在运行时执行这一事实。问题是使用常量SERVICE\u URL=>APIconfig::SERVICE\u URL;在编译时执行,并且您的“require”尚未运行,因此myPackage对APIconfig一无所知 一个令人讨厌的黑客解决方案是将“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
真正的解决方案是将APIconfig重写为一个真正的模块。你暗示你知道这一点,但环境问题阻止你采取这种方法。我强烈建议大家努力解决这些问题,正确地做事。使用和要求之间有两个区别。其中一个会影响你当前的问题,另一个不会。不幸的是,您正在处理一个没有效果的问题 区别在于: 1/“use”调用导入函数,“require”不调用 2/“use”发生在编译时,“require”发生在运行时 您正在通过显式调用“require”来解决“require”不调用import的问题。这不起作用,因为您的模块不导出任何符号,也没有导入子例程 您没有绕过“use”语句在运行时执行这一事实。问题是使用常量SERVICE\u URL=>APIconfig::SERVICE\u URL;在编译时执行,并且您的“require”尚未运行,因此myPackage对APIconfig一无所知 一个令人讨厌的黑客解决方案是将“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
真正的解决方案是将APIconfig重写为一个真正的模块。你暗示你知道这一点,但环境问题阻止你采取这种方法。我强烈建议您尝试解决这些问题,并正确地执行操作。如果是配置文件,请不要编写代码。关于这一点,我在掌握Perl方面有整整一章,CPAN上有许多模块可以帮助您使用几乎任何配置格式 如果它是代码,为什么不把它变成一个模块,这样你就可以使用它了。模块在另一个程序中更容易控制和操作 最简单的解决办法就是不逆潮而行 除此之外,与以下内容相同:
BEGIN {
require Module;
Module->import;
}
只要文件中的代码看起来像模块,就可以对文件名及其定义的命名空间执行相同的操作:
BEGIN {
require "file.pl"; # defines SomeNamespace
SomeNamespace->import;
}
如果它是一个配置文件,不要让它成为代码。关于这一点,我在掌握Perl方面有整整一章,CPAN上有许多模块可以帮助您使用几乎任何配置格式 如果它是代码,为什么不把它变成一个模块,这样你就可以使用它了。模块在另一个程序中更容易控制和操作 最简单的解决办法就是不逆潮而行 除此之外,与以下内容相同:
BEGIN {
require Module;
Module->import;
}
只要文件中的代码看起来像模块,就可以对文件名及其定义的命名空间执行相同的操作:
BEGIN {
require "file.pl"; # defines SomeNamespace
SomeNamespace->import;
}