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

发布于 2024-07-13 12:15:26 字数 306 浏览 13 评论 0原文

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

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

然后在多个模块中使用它们,而无需使用 main::Constants:: 进行限定。 但是,如果我在多个模块中编写 use Constants;,它们只会导入到一个命名空间中。 有没有办法解决?

我正在使用最新的 ActivePerl。

I'm writing an app in Perl with several modules. I want to write some global constants that will be visible from everywhere, like this:

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

And then use them without qualifying with main:: or Constants:: in several modules. However, if I write use Constants; in more than one module, they only get imported into one namespace. Is there any way around this?

I'm using the latest ActivePerl.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

半世蒼涼 2024-07-20 12:15:26

查看 Exporterperlmod man页。

Check out Exporter and the perlmod man page.

月寒剑心 2024-07-20 12:15:26

这段代码应该完全符合您的要求。 将所有荣誉发送给 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__."::"};
}

This chunk of code should do exactly what you want. Send all kudos to 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__."::"};
}
思念满溢 2024-07-20 12:15:26

不要告诉任何人我告诉过你这个,但是 Perl 的特殊变量是
随处可用。 您可能已经注意到,这并不
work:

{ 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 等)但是,

如果您在真实代码中这样做过,那么就有人会谋杀您
:) 不过,最好知道一下,以防万一你看到其他人
正在做。

Don't tell anyone I told you this, but Perl's special variables are
available everywhere. You have probably noticed that this doesn't
work:

{ package Foo;
our $global = 42; }

{ package Bar;
say "global is $global"; }

That's because $global is actually called $Foo::global. You've
also probably noticed that this "rule" doesn't apply to things like
@INC, %ENV, $_, etc. That's because those variables are always
assumed to be in main.

But actually, it's more than just those variables. The entire glob
gets "forced" into main. That means you can write something like
this:

{ package Constants;
  $_{PI} = 3.141592; }

{ package Foo;
  say "pi is $_{PI}"; }

and it will work.

(The same applies for $ENV, &INC, etc.)

If you ever do this in real code, however, expect someone to murder you
:) It is good to know, though, just in case you see someone else
doing it.

天气好吗我好吗 2024-07-20 12:15:26

您可以将其放在 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.


编辑:这个问题也可能有帮助:如何使用 Perl 模块中的常量?

You can put this at the top of Constants.pm:

package main;

In this case all the variables you define will be in the main namespace:

$main::x

or if you're feeling brave:

package;

In this case all the variables you define will be in an empty namespace:

$::x

Note that using package with no namespace is discouraged, and will apparently be deprecated in some versions of Perl. See the quote below.


Quoting from 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.


Edit: This question might be helpful as well: How do I use constants from a Perl module?

夏至、离别 2024-07-20 12:15:26

您可以像这样使用 Exporter

在 Constants.pm 中:

#Constants.pm
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw($h0 $scale);
@EXPORT_OK = qw(myfunc);

$h0 = 0;
$scale = 20;
sub myfunc {...}

注意:
* @EXPORT数组中的&myfunc中的&是可选的,建议您不要使用它。
* 默认情况下,这将导出 $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 ();

You can use Exporter like this:

In Constants.pm:

#Constants.pm
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw($h0 $scale);
@EXPORT_OK = qw(myfunc);

$h0 = 0;
$scale = 20;
sub myfunc {...}

Notes:
* the & in &myfunc in the @EXPORT array is optional, and it's recommended you don't use it.
* This will export $h0 and $scale by default, and &myfunc only if it's requested explicitly (see below how to specify which symbols are imported by the client module)

And then in the module that imports Constants.pm and wants to use $h0, $scale or &myfunc you add the following to import all of the symbols that are in @EXPORT in Constants.pm.

#MyModule.pm
use Constants qw(;

If you want to import only some of the symbols use:

#MyModule.pm
use Constants qw($h0);

And finally, if you don't want to import any of Constant.pm`s symbols use:

#MyModule.pm
use Constants ();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文