从Perl模块导出所有常量(只读变量)的最有效方法是什么?



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

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)

实际常量:

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});
}

如果这些常量可能需要插入到字符串等中,请考虑将相关常量分组为散列,并使用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关于"用于定义常量的CPAN模块"的优秀评论。

回复@CROSP,你可以使用@ikegami的Readonly方法:

In MyConstants.pm

package MyConstants;
<code from answer above>
1;

然后在foo.pl

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

最新更新