我试图使用constant
pragma 在Perl中定义常量:
use constant {
FOO => "bar",
BAR => "foo"
};
Run Code Online (Sandbox Code Playgroud)
我遇到了一些麻烦,并希望有一种标准的处理方式.
首先...
我正在为Subversion定义一个钩子脚本.为了简单起见,我希望有一个文件,我正在使用的类(包)与我的实际脚本在同一个文件中.
这个包中的大部分都会包含常量:
print "This is my program";
package MyClass;
use constant {
FOO => "bar"
};
sub new { ... }
Run Code Online (Sandbox Code Playgroud)
我希望我的常规FOO
可以访问我的主程序.我想这样做而不必将其称为MyClass::FOO
.通常,当包是一个单独的文件时,我可以在我的主程序中执行此操作:
use MyClass qw(FOO);
Run Code Online (Sandbox Code Playgroud)
但是,由于我的课程和程序是单个文件,我不能这样做.对于我的主程序来说,能够访问我班级中定义的常量的最佳方法是什么?
第二个问题......
我想使用常量值作为哈希键:
$myHash{FOO} = "bar";
Run Code Online (Sandbox Code Playgroud)
问题是%myHash
将文字字符串FOO
作为键而不是常量的值.当我做这样的事情时,这会导致问题:
if (defined $myHash{FOO}) {
print "Key " . FOO . " does exist!\n";
}
Run Code Online (Sandbox Code Playgroud)
我可以强制上下文:
if (defined $myHash{"" . FOO . ""}) {
Run Code Online (Sandbox Code Playgroud)
我可以添加括号:
if (defined $myHash{FOO()}) {
Run Code Online (Sandbox Code Playgroud)
或者,我可以使用临时变量:
my $foo = FOO;
if (defined $myHash{$foo}) {
Run Code Online (Sandbox Code Playgroud)
这些都不是处理这个问题的好方法.那么,最好的方法是什么?有没有一种方法我错过了?
顺便说一句,我不想使用,Readonly::Scalar
因为它是1).慢,2).不属于标准Perl包.我想定义我的钩子不要求额外的Perl包并尽可能简单地工作.
Eri*_*rom 20
如果要将所有内容保存在同一文件中,可以按如下方式定义常量包:
use warnings;
use strict;
BEGIN { # BEGIN means this will all happen at compile time
package Constants;
$INC{'Constants.pm'}++; # tell `require` that the package is loaded
use base 'Exporter'; # setup package to export
our @EXPORT_OK = qw( PI ); # what to export
use constant PI => 3.14159; # define your constant
}
package main;
use Constants qw( PI ); # use it like normal
print PI;
Run Code Online (Sandbox Code Playgroud)
然后来愚弄自动报价哈希标里面,你可以写这样的: $hash{+PI}
或$hash{(PI)}
或$hash{PI()}
或$hash{&PI}
或$hash{::PI}
......我大概可以继续下去,但我想你明白了吧.
$INC{'Constants.pm'}++
需要的原因是因为这use Constants qw( PI );
条线真的意味着:
BEGIN {
require 'Constants.pm';
Constants->import( qw( PI ) );
}
Run Code Online (Sandbox Code Playgroud)
并且require
将检查%INC
,看看是否包已被加载.因此,通过给它一个真值(在这种情况下为1),该require 'Constants.pm';
部分use
将成为无操作.