【问题标题】:How can I define constants in a separate file in Perl?如何在 Perl 的单独文件中定义常量?
【发布时间】:2010-11-29 21:09:01
【问题描述】:

我有一堆 Perl 文件,其中包含一些文件名常量。我想在一个单独的文件中定义这些 - 类似于 C 中的头文件。在 Perl 中最好/最标准的方法是什么?

【问题讨论】:

标签: perl constants


【解决方案1】:

一种方法是将它们编写为 perl 模块,随后您可以将其包含在“require”或“use”中。你会这样写你的文件——给它一个 .pm 扩展名(例如,myFabulousPackage.pm)

package myFabulousPackage;

$someSetting=45;
$otherSetting='Fish';

1;

然后在您的 perl 脚本中,这将包含该文件,然后引用 $otherSetting:

#!/usr/bin/perl

use myFabulousPackage;

print $myFabulousPackage::otherSetting;

这只是您可以使用包/模块做什么的一个非常简单的视图,但是对于您的需要,这可能是实现它的最简单方法。同样,您也可以将 sub 放入包中,并以类似的方式引用它们。

【讨论】:

  • 这行不通。使用 my(词法变量)声明的变量无法通过 $PackageName::varname 访问。此语法仅访问符号表中的变量。将变量放入符号表中的最好方法是使用our 来声明它们。
  • 这实际上行不通。变量的my 声明使它们具有词法范围,因此仅对.pm 文件中的代码可见。您希望它们改为使用 our 声明。此外,始终使用1; 终止模块文件是个好主意,因为如果最后一条语句以某种方式计算为假值,则模块将不会加载。
  • 是的——你是对的'我的'......那是我在自动驾驶仪上写 perl,而不是仔细检查我的例子。已编辑。
  • Chris J:你可以用“我们的”代替“我的”
  • 请使用“use strict; use warnings;”,这将阻止您隐式声明新变量。您应该始终使用“我们的”或“我的”,这些 pragma 将强制执行。
【解决方案2】:

我们通常使用模块名称常量来执行此操作。比如:

package MyPackage::Constants;

our $DIR = "/home/chriss";
our $MAX_FILES = 5;

1;

然后,使用它:

package MyPackage;
use MyPackage::Constants;

open(my $fh, ">", $MyPackage::Constants::DIR . "/file");

如果你不想一直引用包,你可以使用 Exporter 并引入所有你想要的符号。

【讨论】:

  • 为什么不在 MyPackage 模块本身中定义 MyPackage 常量,而不是创建一个新的命名空间?如果您将常量称为 namespace::DIR,您将失去继承的优势,即 MyPackage::Child::Constants 不能从 MyPackage::Constants 继承并覆盖 DIR 的值。 namespace->DIR 更好。
  • 这是一个用于说明目的的简单示例。也就是说,并非一切都是面向对象的 :)
  • 这看起来像配置,而不是常量。
  • 另外,为什么将这些声明为变量而不是常量?如思南的帖子所述,请参阅perldoc.perl.org/constant.html
  • brian d foy 说得对,这是配置。然而,在我所做的工作中,“常量”常量很少(没有数学的东西等),所以我所做的大部分工作都是配置。
【解决方案3】:

这听起来像是配置设置,最好将其放入您使用各种 CPAN 模块之一解析的配置文件中,例如 Config::Any

配置是数据,IMO 不应该在您的代码中。

【讨论】:

    【解决方案4】:

    Perl 中没有与 C 头文件等效的东西。要声明和定义全局常量,您可以使用define pragma。尽管界面看起来很合理,但我没有使用此模块的经验。

    另一方面,您可以编写一个定义常量的模块,然后使用use 将它们导入到您的模块中。例如:

    package MyConstants;
    
    use strict; use warnings;
    
    use Exporter qw( import );
    use Const::Fast;
    
    our @EXPORT = qw();
    our @EXPORT_OK = qw( $X $Y );
    
    const our $X => 'this is X';
    const our $Y => 'this is Y';
    
    __PACKAGE__;
    __END__
    

    然后您可以按如下方式使用此模块:

    #!/usr/bin/perl
    
    use strict; use warnings;
    
    use MyConstants qw( $X );
    
    print "$X\n";
    print "$MyConstants::Y\n";
    

    如果您可以使用完全限定的变量名(例如$MyConstants::Y),则根本不需要Exporter

    此外,请确保您导出的变量不可在其他地方修改(请参阅 Exporter 文档中的注意事项)。

    当然,您也可以使用constant.pm 定义常量。使用此类常量可能会更快,但如果您需要将它们插入字符串中,它们会很尴尬。

    【讨论】:

    • 如果您安装了 Readonly::XS,Readonly::Scalar 也相当快。哈希和数组仍然比较慢。
    • 请注意,导出器文档 (perldoc.perl.org/Exporter.html) 建议您不要导出变量,即使它允许您这样做。
    • @Robert P,IMO 根据请求导出变量是合理的,最好避免默认导出一个(或多个!)。如果在上面的示例中,我希望多次使用 $X 并希望避免在任何地方不必要地重复键入 $MyConstants::X,这将是一个巨大的好处。导入变量的另一种情况是,如果我不小心尝试使用$MyConstants::x,没有strict 生成的错误消息会提醒我我的错误,而如果我导入$X 并尝试使用$x,严格保存发现错误的一天。
    • 我会买那个。我通常使用use constant 表单,然后将其导出。如果我使用的是 Readonly 包,那可能合乎逻辑。
    • @Robert P:在这种情况下导出的变量是不可修改的(我的答案链接到文档中关于导出变量的警告)。
    猜你喜欢
    • 1970-01-01
    • 2020-12-15
    • 2014-06-06
    • 1970-01-01
    • 1970-01-01
    • 2018-07-31
    • 2020-05-13
    • 2018-07-23
    • 2018-02-12
    相关资源
    最近更新 更多