如何在Perl中将常量导入多个模块?

时间:2009-02-08 10:37:07

标签: perl constants activeperl

我正在用Perl编写一个带有几个模块的应用程序。我想编写一些从任何地方都可以看到的全局常量,如下所示:

#Constants.pm
$h0 = 0;
$scale = 20;

然后在几个模块中使用main::Constants::时无需使用它们。但是,如果我在多个模块中编写use Constants;,它们只会导入到一个名称空间中。有没有办法解决这个问题?

我正在使用最新的ActivePerl。

5 个答案:

答案 0 :(得分:7)

查看Exporterperlmod手册页。

答案 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 ();
相关问题