【问题标题】:How do I export Readonly variables with mod_perl?如何使用 mod_perl 导出只读变量?
【发布时间】:2009-04-09 23:40:59
【问题描述】:

我试图通过创建一个导出整本书中使用的几个标量的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 无法做到这一点吗?

【问题讨论】:

    标签: perl readonly mod-perl exporter


    【解决方案1】:

    你有 4 个问题:

    1. 您没有包括strictwarnings 编译指示
    2. 最好通过base pragma 包含exporter(因为它为您设置了@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 有一个 mechanism 用于加载与脚本本身分开的模块。此加载仅发生一次,因此您应该使用它。

    【讨论】:

    • 我已经在做 1、3 和 4,为了简洁起见,我只是将它们排除在示例之外。此外,使用 Exporter qw(import) 是首选方法,而不是使用 base qw(Exporter)。将模块添加到 PerlRequire 仍然会产生错误,每个启动的 http 进程都有一个错误。
    • 另外,您是否删除了“use Example::Constants;”来自你的脚本?
    • 这对我有用!为了完整起见,也许您也可以在问题中包含使用它的代码:使用 Example::Constants;打印 $EMPTY_STRING 。 '富' 。 $EMPTY_STRING;
    【解决方案2】:

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

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

    -- 埃里克

    【讨论】:

    • 太棒了!非常感谢。如果重要的话,我也在使用 Readonly::XS 模块。
    • 嗯,埃里克,已经一年了。这方面有什么进展吗? :)
    【解决方案3】:

    我没有方便测试的 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 常量似乎很完美,因为该技术的巨大限制(它需要一个全局包)在这里不是问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-16
      • 2014-11-21
      • 2017-07-27
      • 2022-09-28
      • 2016-01-11
      • 2010-10-07
      • 2021-08-01
      • 2018-05-12
      相关资源
      最近更新 更多