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

发布于 2024-07-17 01:06:09 字数 897 浏览 14 评论 0原文

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

I'm trying to make it easier to follow some Perl Best Practices by creating a Constants module that exports several of the scalars used throughout the book. One in particular, $EMPTY_STRING, I can use in just about every Perl script I write. What I'd like is to automatically export these scalars so I can use them without defining them explicitly in each script.

#!perl
package Example::Constants;

use Exporter qw( import );
use Readonly;

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

An example usage:

#!perl
use Example::Constants;
print $EMPTY_STRING . 'foo' . $EMPTY_STRING;

Using the above code produces an error:

Global symbol "$EMPTY_STRING" requires explicit package name

If I change the Readonly declaration to:

Readonly our $EMPTY_STRING => q{}; # 'our' instead of 'my'

The error becomes:

Attempt to reassign a readonly scalar

Is this just not possible with mod_perl?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蒲公英的约定 2024-07-24 01:06:09

您有 4 个问题:

  1. 您没有包含 strictwarnings 编译指示
  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 有一个 机制 用于加载与脚本本身。 此加载仅发生一次,因此您应该使用它。

You had 4 problems:

  1. You weren't including the strict and warnings pragmas
  2. It is better to include exporter through the base pragma (since it sets @ISA for you)
  3. Only package variables (i.e. our variables) can be exported
  4. Modules must end with a true value

Here is the corrected module.

package Example::Constants;

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

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

1;

Hmm, I missed the bit about attempting to assign to a readonly, it sounds like the module is getting loaded more than once. I believe mod_perl has a mechanism for loading modules separate from the scripts themselves. This loading happens only once, so you should be using it.

聽兲甴掵 2024-07-24 01:06:09

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

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

-- Eric

I'm the author of the Readonly module. The next version of Readonly will provide support for mod_perl, specifically because of this problem.

I know this doesn't solve your problem now, but... well, I'm working on it :-)

-- Eric

暮凉 2024-07-24 01:06:09

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

I don't have a mod_perl instance handy to test with, so I can't test these suggestions. I hope they pan out.

Try using Scalar::Util::readonly to check if the variable has already been marked read only.

#!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{};
}

You could also try 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 );

You could also use a typeglob constant:

#!perl
package Example::Constants;

use Exporter qw( import );
use Readonly;

our $EMPTY_STRING;
*EMPTY_STRING = \q{};
our @EXPORT = qw( $EMPTY_STRING );

Using a typeglob constant seems perfect, since the big limitation of the technique (it requires a package global) is not an issue here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文