如何使用 Perl 模块中的常量?

Posted

技术标签:

【中文标题】如何使用 Perl 模块中的常量?【英文标题】:How do I use constants from a Perl module? 【发布时间】:2010-09-16 14:53:30 【问题描述】:

如果我在 Perl 模块中定义一个常量,我如何在我的主程序中使用该常量? (或者我如何在主程序中调用该常量?)

【问题讨论】:

最好避免使用“常量”包。 earino.wordpress.com/2013/02/27/… 这里的替代品:neilb.org/reviews/constants.html @null 仅仅因为有人讨厌他们与哈希初始化器中的 Perl 裸字行为发生冲突?谢谢,但不,谢谢。大量核心模块毫无问题地使用它。编码、Compress::Raw::Bzip2/Zlib、Data::Dumper、File::Spec等 【参考方案1】:

常量可以像其他包符号一样被导出。使用标准的Exporter 模块,您可以像这样从包中导出常量:

package Foo;
use strict;
use warnings;

use base 'Exporter';

use constant CONST => 42;

our @EXPORT_OK = ('CONST');

1;

然后,在客户端脚本(或其他模块)中

use Foo 'CONST';
print CONST;

您可以使用%EXPORT_TAGS 哈希(请参阅导出器文档)来定义可以使用单个导入参数导出的常量组。

更新:如果您有多个常量,以下是如何使用 %EXPORT_TAGS 功能的示例。

use constant LARRY => 42;
use constant CURLY => 43;
use constant MOE   => 44;

our @EXPORT_OK = ('LARRY', 'CURLY', 'MOE');
our %EXPORT_TAGS = ( stooges => [ 'LARRY', 'CURLY', 'MOE' ] );

那你可以说

use Foo ':stooges';
print "$_\n" for LARRY, CURLY, MOE;

【讨论】:

使用出口商'进口';更好,但需要在 5.8.3 之前的 perl 上升级 Exporter。 请解释为什么使用'import'更好? 最好避免使用“常量”包。 earino.wordpress.com/2013/02/27/… 这里的替代品:neilb.org/reviews/constants.html @nslntmnx use constant 基准测试很好,一般来说。确实应该阅读它的文档。【参考方案2】:

常量只是带有空原型的子,所以它们可以像任何其他子一样被导出。

# file Foo.pm
package Foo;
use constant BAR => 123;
use Exporter qw(import);
our @EXPORT_OK = qw(BAR);


# file main.pl:
use Foo qw(BAR);
print BAR;

【讨论】:

【参考方案3】:

为了扩展之前的答案,由于常量实际上只是子类,您可以直接调用它们:

use Foo;
print Foo::BAR;

【讨论】:

不要将答案称为上面,因为如果您的答案得到足够的投票,它可能最终会超过他们。【参考方案4】:

您可能需要考虑使用Readonly 而不是常量。

【讨论】:

你不能这样做: print "constant is $constant";或者这个:打印 $hashconstant; 由于 'use constant' 创建了一个子例程,出现了意想不到的问题 => 没有字符串插值,难以用作哈希键。请参阅 Readonly [metacpan.org/module/Readonly#COMPARISON-WITH-use-constant] 的文档。 Readonly 使用 perl 内部直接将变量标记为只读。 Readonly 很慢(除非使用 Readonly::XS)并且没有维护。另请参阅 Data::Lock 和 Const::Fast 以了解不同的实现。 实际上你可以在字符串中插入常量。只需使用与任何其他函数相同的语法:use constant COLOR => 'red'; print "The color is @[COLOR]!";【参考方案5】:
package Foo;
use Readonly;
Readonly my  $C1 => 'const1';
Readonly our $C2 => 'const2';
sub get_c1  return $C1 
1;

perl -MFoo -e 'print "$_\n" for Foo->get_c1, $Foo::C2'

【讨论】:

【参考方案6】:

为了增加技巧,由于常量只是一个子例程,您甚至可以将其作为类方法调用。

package Foo;
use constant PI => 3.14;

print Foo->PI;

如果您有很多常量,这是一种很好的方式来获取偶尔的常量,而无需将它们全部导出。但是,与Foo::PI 或导出PI 不同,Perl 不会编译出Foo->PI,因此您会产生方法调用的成本(这可能无关紧要)。

【讨论】:

以上是关于如何使用 Perl 模块中的常量?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Perl 中的 Win32::LongPath 模块来操作长路径名?

如何在没有安装权限的情况下使用新的 Perl 模块?

Perl 如何使用 DBI 模块更改帐户主机?

如何在 Perl 中解决 Windows 和 Linux 客户端的“常量标志”?

如何覆盖模块中的类常量和方法?

如何遍历 JavaScript 中的静态值(常量)列表? [复制]