我试图通过创建一个导出本书中使用的几个标量的Constants
模块来更轻松地关注某些Perl Best Practices。特别是$EMPTY_STRING
,我可以在我写的每个Perl脚本中使用它。我想要的是自动导出这些标量,这样我就可以使用它们,而无需在每个脚本中明确定义它们。
#!perl
package Example::Constants;
use Exporter qw( import );
use Readonly;
Readonly my $EMPTY_STRING => q{};
our @EXPORT = qw( $EMPTY_STRING );
示例用法:
#!perl
use Example::Constants;
print $EMPTY_STRING . 'foo' . $EMPTY_STRING;
使用上面的代码会产生错误:
Global symbol "$EMPTY_STRING" requires explicit package name
如果我将Readonly
声明更改为:
Readonly our $EMPTY_STRING => q{}; # 'our' instead of 'my'
错误变为:
Attempt to reassign a readonly scalar
这对mod_perl来说是不可能的吗?
答案 0 :(得分:4)
我是Readonly模块的作者。 Readonly的下一个版本将提供对mod_perl的支持,特别是因为这个问题。
我知道这不能解决你的问题现在,但是......好吧,我正在研究它: - )
- Eric
答案 1 :(得分:3)
你有4个问题:
strict
和warnings
pragma base
pragma包含导出器(因为它为您设置@ISA
)our
变量)这是更正的模块。
package Example::Constants;
use strict;
use warnings;
use base 'Exporter';
use Readonly;
Readonly our $EMPTY_STRING => q{};
our @EXPORT = qw( $EMPTY_STRING );
1;
嗯,我错过了关于尝试分配给readonly的一点,听起来这个模块不止一次被加载。我相信mod_perl有一个mechanism用于加载与脚本本身分开的模块。此加载仅发生一次,因此您应该使用它。
答案 2 :(得分:1)
我没有方便测试的mod_perl实例,所以我无法测试这些建议。我希望他们能够成功。
尝试使用Scalar::Util::readonly
检查变量是否已标记为只读。
#!perl
package Example::Constants;
use Exporter qw( import );
use Readonly;
use Scalar::Util qw(readonly);
our $EMPTY_STRING;
our @EXPORT = qw( $EMPTY_STRING );
if ( !readonly( $EMPTY_STRING ) ) {
Readonly $EMPTY_STRING => q{};
}
您也可以尝试use vars
:
#!perl
package Example::Constants;
use Exporter qw( import );
use Readonly;
use vars qw( $EMPTY_STRING );
Readonly $EMPTY_STRING => q{};
our @EXPORT = qw( $EMPTY_STRING );
您还可以使用typeglob常量:
#!perl
package Example::Constants;
use Exporter qw( import );
use Readonly;
our $EMPTY_STRING;
*EMPTY_STRING = \q{};
our @EXPORT = qw( $EMPTY_STRING );
使用typeglob常量看起来很完美,因为该技术的大限制(它需要一个包全局)在这里不是问题。