【问题标题】:Why does Perl complain when I use a hash reference with constant.pm?为什么当我在 constant.pm 中使用散列引用时 Perl 会报错?
【发布时间】:2009-02-03 18:22:17
【问题描述】:

我有 perl, v5.6.1 为 ActiveState 提供的 MSWin32-x86-multi-thread Binary build 638 构建。

我正在编写一个 Perl 脚本,我在其中声明了稍后用于比较目的的常量。出于某种原因,我收到一个错误,指出常量名称行中的某些内容在脚本的第 31 行有无效字符(下面代码中使用常量子句之后的行)。我检查并发现常量名称中的“_”(下划线)是合法字符。我还尝试将 '0.00' 更改为 '0' 以查看这是否是原因,但我得到了同样的错误。我不确定我做错了什么。有谁知道为什么编译器不喜欢这个?

谢谢!

代码如下:

use constant {
MIN_NET_DLR => 0.00,
MAX_NET_DLR => 99.99,
MIN_SUM_DLR => 0.00,
MAX_SUM_DLR => 999.99,
MIN_UNITS => 0,
MAX_UNITS => 99,
MIN_SUM_UNITS => 0,
MAX_SUM_UNITS => 999,
PCT_THRES_AO => 1,
PCT_THRES_TRANS_CUST_BI => 20,
PCT_THRES_CUST => 3,
};

问题:

问题是perl 5.6.1提供的常量版本不支持hash引用。

解决方案:

对常量使用常规声明。因此,声明将如下所示:

use constant MIN_NET_DLR => 0.00;
use constant MAX_NET_DLR => 99.99;
use constant MIN_SUM_DLR => 0.00;
use constant MAX_SUM_DLR => 999.99;
use constant MIN_UNITS => 0;
use constant MAX_UNITS => 99;
use constant MIN_SUM_UNITS => 0;
use constant MAX_SUM_UNITS => 999;
use constant PCT_THRES_AO =>    1;
use constant PCT_THRES_TRANS_CUST_BI => 20;
use constant PCT_THRES_CUST => 3;

感谢@leon 的解决方案以及其他提供意见的人。

更新:另一种(更优雅的)解决方案是将您的 Perl 版本更新为在声明常量时支持散列引用的版本。

【问题讨论】:

  • 如果删除最后一个逗号会怎样?
  • Perl 的哪个版本?您的代码在 Perl 5.8.8 上运行良好。如果您的示例从第 30 行开始,则错误可能位于您粘贴的一小段代码之上。
  • 我只将常量声明部分移至测试脚本并运行它,但仍然出现错误。我在 Windows XP 中运行 ActivePerl 是否重要?如果它为你运行,它可能对我来说是一个环境问题。
  • 它在 WinXp 上与 ActivePerl 配合得很好。
  • 我有 perl, v5.6.1 为 MSWin32-x86-multi-thread Binary build 638 构建,由 ActiveState Corp. 提供。

标签: perl constants


【解决方案1】:

问题在于您使用的是哈希引用。 perl 5.6.1 提供的constant 版本不支持。您要么必须移除大括号,要么升级您的constant

【讨论】:

  • 感谢 Leon 并感谢所有参与帮助的人。问题是我使用的是哈希引用。一旦我在每个常量前面声明了 use 常量,它就消失了。更好的解决方案当然是升级,但我运行的脚本很少,所以必须等待。谢谢!
  • ...或使用括号创建真正的哈希而不是 hashref。
【解决方案2】:

它在 perl5.8 上对我来说很好,但在 perl5.6 上不起作用。错误信息是:

无法将“HASH(0x80c05d8)”定义为常量(名称包含无效字符或为空)

好像是老版本的问题,应该是 Leon described 的问题。

【讨论】:

    【解决方案3】:

    您的旧 perl 可能不支持在一个语句中声明多个常量的语法。尝试像这样分别定义每个常量...

    use constant MAX_NET_DLR => 99.99;
    

    【讨论】:

    • @noswonky - 谢谢。我昨天试过了,它奏效了。我会用答案更新问题。
    【解决方案4】:

    我会使用Readonly 模块。

    常量的缺点是,它会在调用者命名空间内创建一个返回常量值的函数。

    Readonly 可用于声明标量、数组和哈希只读(实常数)。

    【讨论】:

    • 在使用 Readonly 时,注意哈希和数组的性能损失也很重要(如果你有 Readonly::XS,标量很好)。此外,由常量创建的常量可以在编译期间以“sleep(60*WAIT_MINUTES);”等表达式解析。或 "debug($str) if DEBUG;"
    【解决方案5】:

    为我工作。您确定该代码中的某处没有任何控制字符吗?

    【讨论】:

    • 我只将常量声明部分移动到测试脚本并运行它,但仍然出现错误。我在 Windows XP 中运行 ActivePerl 是否重要?如果它为你运行,它可能对我来说是一个环境问题。
    • 可能 - 我在 linux 上测试。
    【解决方案6】:

    删除此行末尾的最后一个逗号:

    PCT_THRES_CUST => 3,
    

    这可能是问题所在。

    【讨论】:

    • 逗号一直是允许的。
    • Perl 允许在列表中使用逗号。
    猜你喜欢
    • 2010-12-07
    • 2015-07-23
    • 1970-01-01
    • 2023-02-25
    • 2022-07-06
    • 2016-09-08
    • 1970-01-01
    • 2020-03-31
    相关资源
    最近更新 更多