【问题标题】:How do I use constants from a Perl module?如何使用 Perl 模块中的常量?
【发布时间】: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等

标签: perl module export constants


【解决方案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";或者这个:打印 $hash{constant};
    • 由于 '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,因此您会产生方法调用的成本(这可能无关紧要)。

      【讨论】:

        猜你喜欢
        • 2010-10-06
        • 2011-11-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多