4

我试图通过创建一个导出本书中使用的几个标量的模块来更容易地遵循一些Perl 最佳实践。Constants特别是$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 来说是不可能的吗?

4

3 回答 3

4

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

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

——埃里克

于 2009-04-13T21:59:24.850 回答
4

你有4个问题:

  1. 你没有包括strictand warningspragmas
  2. 最好通过base编译指示包含出口商(因为它@ISA为您设置)
  3. our只能导出包变量(即变量)
  4. 模块必须以真值结尾

这是更正后的模块。

package Example::Constants;

use strict;
use warnings;
use base 'Exporter';
use Readonly;

Readonly our $EMPTY_STRING => q{};
our @EXPORT = qw( $EMPTY_STRING );

1;

嗯,我错过了尝试分配给只读的一点,听起来模块不止一次被加载。我相信 mod_perl 有一种机制来加载与脚本本身分开的模块。此加载仅发生一次,因此您应该使用它。

于 2009-04-10T00:57:41.787 回答
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 常量似乎很完美,因为该技术的巨大限制(它需要一个全局包)在这里不是问题。

于 2009-04-12T06:43:49.410 回答