我正在用Perl编写一个带有几个模块的应用程序。我想编写一些从任何地方都可以看到的全局常量,如下所示:
#Constants.pm
$h0 = 0;
$scale = 20;
然后在几个模块中使用main::
或Constants::
时无需使用它们。但是,如果我在多个模块中编写use Constants;
,它们只会导入到一个名称空间中。有没有办法解决这个问题?
我正在使用最新的ActivePerl。
答案 0 :(得分:7)
查看Exporter和perlmod
手册页。
答案 1 :(得分:7)
这段代码应该完全符合您的要求。将所有荣誉发送至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__."::"};
}
答案 2 :(得分:5)
不要告诉任何我告诉你的人,但是Perl的特殊变量是 随处可用。您可能已经注意到这不是 工作:
{ package Foo;
our $global = 42; }
{ package Bar;
say "global is $global"; }
那是因为$global
实际上被称为$Foo::global
。你已经
也可能注意到这个“规则”不适用于像
@INC
,%ENV
,$_
等。这是因为这些变量总是如此
假设在main
。
但实际上,它不仅仅是那些变量。整个水珠
被“强迫”进入main
。这意味着你可以写出像
这样:
{ package Constants;
$_{PI} = 3.141592; }
{ package Foo;
say "pi is $_{PI}"; }
它会起作用。
(这同样适用于$ENV
,&INC
等。)
但是,如果您在实际代码中执行此操作,则期望有人谋杀您 :)不过,最好知道,以防你看到其他人 这样做。
答案 3 :(得分:2)
您可以将其放在Constants.pm
:
package main;
在这种情况下,您定义的所有变量都将位于main
命名空间中:
$main::x
或者如果你感到勇敢:
package;
在这种情况下,您定义的所有变量都将位于空命名空间中:
$::x
请注意,不鼓励使用不带命名空间的package
,并且在某些版本的Perl中显然会弃用。请参阅下面的引用。
引自man perlfunc
:
package NAMESPACE package Declares the compilation unit as being in the given namespace. The scope of the package declaration is from the declaration itself through the end of the enclosing block, file, or eval (the same as the "my" operator). All further unqualified dynamic identifiers will be in this namespace. A package statement affects only dynamic variables--including those you've used "local" on--but not lexical variables, which are cre? ated with "my". Typically it would be the first decla? ration in a file to be included by the "require" or "use" operator. You can switch into a package in more than one place; it merely influences which symbol table is used by the compiler for the rest of that block. You can refer to variables and filehandles in other packages by prefixing the identifier with the package name and a double colon: $Package::Variable. If the package name is null, the "main" package as assumed. That is, $::sail is equivalent to $main::sail (as well as to $main'sail, still seen in older code). If NAMESPACE is omitted, then there is no current pack? age, and all identifiers must be fully qualified or lexicals. However, you are strongly advised not to make use of this feature. Its use can cause unexpected behaviour, even crashing some versions of Perl. It is deprecated, and will be removed from a future release.
修改:此问题也可能有用:How do I use constants from a Perl module?
答案 4 :(得分:2)
您可以像这样使用Exporter:
在Constants.pm中:
#Constants.pm
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw($h0 $scale);
@EXPORT_OK = qw(myfunc);
$h0 = 0;
$scale = 20;
sub myfunc {...}
注意:
* &
数组中&myfunc
中的@EXPORT
是可选的,建议您不要使用它。
*默认情况下会导出$h0
和$scale
,并且只有在明确请求时才会导出& myfunc(请参阅下面如何指定客户端模块导入的符号)
然后在导入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 ();