代码之家  ›  专栏  ›  技术社区  ›  cowgod

如何使用mod_perl导出只读变量?

  •  3
  • cowgod  · 技术社区  · 15 年前

    我试着让你更容易跟上 Perl Best Practices 通过创建 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中是不可能的吗?

    3 回复  |  直到 11 年前
        1
  •  4
  •   Chas. Owens    15 年前

    你有4个问题:

    1. 你没有包括 strict warnings 布拉格
    2. 最好通过 base pragma(因为它设置了 @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;
    

    嗯,我错过了尝试分配给readonly的那一点,听起来模块被加载了不止一次。我相信mod_perl有一个 mechanism 用于加载独立于脚本本身的模块。这种加载只发生一次,所以您应该使用它。

        2
  •  4
  •   Eric RoodeEric Roode    15 年前

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

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

    --埃里克

        3
  •  1
  •   daotoad    15 年前

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