如何使用 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 @nslntmnxuse 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 模块来操作长路径名?