5

我正在用 Perl 编写一个包含多个模块的应用程序。我想编写一些在任何地方都可见的全局常量,如下所示:

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

然后在没有限定条件的情况下使用它们,main::或者Constants::在几个模块中使用它们。但是,如果我编写use Constants;多个模块,它们只会被导入一个命名空间。有没有办法解决?

我正在使用最新的 ActivePerl。

4

5 回答 5

7

查看Exporterperlmod手册页。

于 2009-02-08T14:15:55.353 回答
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__."::"};
}
于 2011-07-06T02:25:22.467 回答
5

不要告诉任何人我告诉过你这个,但是 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等)

但是,如果您曾经在真实代码中这样做过,预计有人会谋杀您 :) 不过,很高兴知道,以防万一您看到其他人这样做。

于 2009-02-09T07:28:28.810 回答
2

你可以把它放在顶部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 模块中的常量?

于 2009-02-08T11:31:25.513 回答
2

您可以像这样使用导出器

在常量.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 ();
于 2009-02-11T20:37:53.053 回答