【问题标题】:What is the most efficient way to export all constants (Readonly variables) from Perl module从 Perl 模块导出所有常量(只读变量)的最有效方法是什么
【发布时间】:2015-08-06 17:49:19
【问题描述】:

我正在寻找从我的单独模块中导出所有常量的最有效和可读的方法,该模块仅用于存储常量。
比如

use strict;
use warnings;

use Readonly;

Readonly our $MY_CONSTANT1         => 'constant1';
Readonly our $MY_CONSTANT2    => 'constant2'; 
....
Readonly our $MY_CONSTANT20    => 'constant20';

所以我有很多变量,并将它们全部列在我们的@EXPORT = qw( MY_CONSTANT1.... );
这会很痛苦。是否有任何优雅的方式来导出所有常量,在我的情况下为只读变量(强制导出全部,不使用@EXPORT_OK)。

【问题讨论】:

    标签: perl constants perl-module perl-exporter


    【解决方案1】:

    实际常量:

    use constant qw( );
    use Exporter qw( import );    
    
    our @EXPORT_OK;
    
    my %constants = (
       MY_CONSTANT1 => 'constant1',
       MY_CONSTANT2 => 'constant2',
       ...
    );
    
    push @EXPORT_OK, keys(%constants);
    constant->import(\%constants);
    

    使用 Readonly 将变量设为只读:

    use Exporter qw( import );
    use Readonly qw( Readonly );
    
    our @EXPORT_OK;
    
    my %constants = (
       MY_CONSTANT1 => 'constant1',
       MY_CONSTANT2 => 'constant2',
       #...
    );
    
    for my $name (keys(%constants)) {
       push @EXPORT_OK, '$'.$name;
       no strict 'refs';
       no warnings 'once';
       Readonly($$name, $constants{$name});
    }
    

    【讨论】:

    • 感谢您的回答,您能提供一个在这两种情况下都使用常量的示例吗?
    【解决方案2】:

    如果这些是可能需要插入到字符串等中的常量,请考虑将相关常量分组到散列中,并使用Const::Fast 制作散列常量。这减少了命名空间污染,允许您检查特定组中的所有常量等。例如,考虑 IE 的 ReadyState 属性的 READYSTATE 枚举值。您可以将它们分组到一个哈希中,而不是为每个值创建一个单独的变量或单独的常量函数:

    package My::Enum;
    
    use strict;
    use warnings;
    
    use Exporter qw( import );
    our @EXPORT_OK = qw( %READYSTATE );
    
    use Const::Fast;
    
    const our %READYSTATE => (
        UNINITIALIZED => 0,
        LOADING => 1,
        LOADED => 2,
        INTERACTIVE => 3,
        COMPLETE => 4,
    );
    
    __PACKAGE__;
    __END__
    

    然后,您可以直观地使用它们,如下所示:

    use strict;
    use warnings;
    
    use My::Enum qw( %READYSTATE );
    
    for my $state (sort { $READYSTATE{$a} <=> $READYSTATE{$b} } keys %READYSTATE) {
        print "READYSTATE_$state is $READYSTATE{$state}\n";
    }
    

    另见Neil Bowers' excellent review on 'CPAN modules for defining constants'

    【讨论】:

      【解决方案3】:

      回复@CRROSP,您可以像这样使用@ikegami 的Readonly 方法:

      MyConstants.pm

      package MyConstants;
      <code from answer above>
      1;
      

      然后在foo.pl

      use MyConstants qw($MY_CONSTANT1, $MY_CONSTANT2);
      print "This is $MY_CONSTANT1\n";
      

      【讨论】:

        猜你喜欢
        • 2020-02-16
        • 2015-11-21
        • 2010-10-11
        • 2010-09-27
        • 1970-01-01
        • 1970-01-01
        • 2014-02-01
        • 2020-01-28
        • 2019-03-05
        相关资源
        最近更新 更多