我正在用 Perl 编写一个包含多个模块的应用程序。我想编写一些在任何地方都可见的全局常量,如下所示:
#Constants.pm
$h0 = 0;
$scale = 20;
然后在没有限定条件的情况下使用它们,main::
或者Constants::
在几个模块中使用它们。但是,如果我编写use Constants;
多个模块,它们只会被导入一个命名空间。有没有办法解决?
我正在使用最新的 ActivePerl。
我正在用 Perl 编写一个包含多个模块的应用程序。我想编写一些在任何地方都可见的全局常量,如下所示:
#Constants.pm
$h0 = 0;
$scale = 20;
然后在没有限定条件的情况下使用它们,main::
或者Constants::
在几个模块中使用它们。但是,如果我编写use Constants;
多个模块,它们只会被导入一个命名空间。有没有办法解决?
我正在使用最新的 ActivePerl。
查看Exporter和perlmod
手册页。
这段代码应该完全符合您的要求。向lkundrak 致敬。
package Constants;
use base qw/Exporter/;
use constant BOB => 666;
use constant ALICE => 555;
sub import {
no strict "refs";
${[caller]->[0].'::'}{$_} = ${__PACKAGE__."::"}{$_}
foreach grep { not /^(ISA|isa|BEGIN|import|Dumper)$/ }
keys %{__PACKAGE__."::"};
}
不要告诉任何人我告诉过你这个,但是 Perl 的特殊变量无处不在。您可能已经注意到这不起作用:
{ package Foo;
our $global = 42; }
{ package Bar;
say "global is $global"; }
那是因为$global
实际上被称为$Foo::global
. 您可能还注意到,此“规则”不适用于
@INC
, %ENV
,$_
等。那是因为这些变量总是假定在main
.
但实际上,它不仅仅是那些变量。整个 glob 被“强制”进入main
. 这意味着您可以编写如下内容:
{ package Constants;
$_{PI} = 3.141592; }
{ package Foo;
say "pi is $_{PI}"; }
它会起作用。
(同样适用于$ENV
,&INC
等)
但是,如果您曾经在真实代码中这样做过,预计有人会谋杀您 :) 不过,很高兴知道,以防万一您看到其他人这样做。
你可以把它放在顶部Constants.pm
:
package main;
在这种情况下,您定义的所有变量都将位于main
命名空间中:
$main::x
或者如果你觉得勇敢:
package;
在这种情况下,您定义的所有变量都将位于一个空的命名空间中:
$::x
请注意,package
不鼓励使用没有命名空间,并且在某些 Perl 版本中显然不推荐使用。请参阅下面的报价。
引自man perlfunc
:
包命名空间 package 将编译单元声明为在给定的 命名空间。包声明的范围是 从声明本身到结束 封闭块、文件或 eval(与“my”相同) 操作员)。所有其他不合格的动态标识符 将在此命名空间中。包声明影响 只有动态变量——包括你使用过的变量 “local” on--但不是词法变量,它们是 cre? 与“我的”一起吃。通常它会是第一个声明? 配给文件中的“要求”或 “使用”运算符。您可以在更多中切换到一个包 不止一处;它只影响哪个符号表 由编译器用于该块的其余部分。 您可以参考其他变量和文件句柄 通过在标识符前面加上包的前缀来打包 名称和双冒号:$Package::Variable。如果 包名称为空,假定为“主”包。 也就是说,$::sail 等价于 $main::sail(同样 至于 $main'sail,仍然可以在旧代码中看到)。 如果 NAMESPACE 被省略,那么没有当前包? 年龄,并且所有标识符必须是完全限定的或 词汇。但是,强烈建议您不要 使用此功能。它的使用可能会导致意外 行为,甚至使某些版本的 Perl 崩溃。这是 已弃用,并将从将来的版本中删除。
编辑:这个问题也可能有帮助:如何使用 Perl 模块中的常量?
您可以像这样使用导出器:
在常量.pm 中:
#Constants.pm
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw($h0 $scale);
@EXPORT_OK = qw(myfunc);
$h0 = 0;
$scale = 20;
sub myfunc {...}
注意:
* 数组中的in&
是可选的,建议不要使用。* 这将在默认情况下导出和,并且只有在明确请求时才会导出 &myfunc(请参阅下文如何指定客户端模块导入的符号)&myfunc
@EXPORT
$h0
$scale
然后在导入 Constants.pm 并希望使用的模块中$h0
,$scale
或者&myfunc
添加以下内容以导入Constants.pm 中的所有符号@EXPORT
。
#MyModule.pm
use Constants qw(;
如果您只想导入一些符号,请使用:
#MyModule.pm
use Constants qw($h0);
最后,如果您不想导入任何 Constant.pm 的符号,请使用:
#MyModule.pm
use Constants ();