如何使用mod_perl导出Readonly变量?

时间:2009-04-09 23:40:59

标签: perl readonly mod-perl exporter

我试图通过创建一个导出本书中使用的几个标量的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来说是不可能的吗?

3 个答案:

答案 0 :(得分:4)

我是Readonly模块的作者。 Readonly的下一个版本将提供对mod_perl的支持,特别是因为这个问题。

我知道这不能解决你的问题现在,但是......好吧,我正在研究它: - )

- Eric

答案 1 :(得分:3)

你有4个问题:

  1. 您未包括strictwarnings pragma
  2. 最好通过base pragma包含导出器(因为它为您设置@ISA
  3. 只能导出包变量(即our变量)
  4. 模块必须以真值结束
  5. 这是更正的模块。

    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常量看起来很完美,因为该技术的大限制(它需要一个包全局)在这里不是问题。