我有一个Perl脚本,其中包含许多定义的配置文件常量。
use constant {
LOG_DIR => "/var/log/",
LOG_FILENAME => "/var/log/file1.log",
LOG4PERL_CONF_FILE => "/etc/app1/log4perl.conf",
CONF_FILE1 => "/etc/app1/config1.xml",
CONF_FILE2 => "/etc/app1/config2.xml",
CONF_FILE3 => "/etc/app1/config3.xml",
CONF_FILE4 => "/etc/app1/config4.xml",
CONF_FILE5 => "/etc/app1/config5.xml",
};
我想减少"/etc/app1 "和"/var/log"的重复,但使用变量不起作用。同样,使用先前定义的常量在同一个"use constant block"中也不起作用。例如:
use constant {
LOG_DIR => "/var/log/",
FILE_FILENAME => LOG_DIR . "file1.log"
};
不起作用。
使用单独的"use constant"块确实可以解决这个问题,但是这会增加很多不必要的代码。
正确的做法是什么?
谢谢你。
5条答案
按热度按时间xmq68pz91#
使用单独的"use constant"块确实可以解决这个问题,但是这会增加很多不必要的代码。
真的吗?
我看不出这有什么问题。你只在一个点上指定了基路径,因此遵守了DRY原则。如果你给BASE_PATH赋值一个环境变量:
...你就有了一个不需要编辑代码就可以重新配置常量的廉价方法。有什么不喜欢的呢?
如果您真的想减少重复的"BASE_PATH."连接,您可以添加一些机制来自己安装常量并将其分解掉:
但在这一点上,我认为平衡已经从正确转向了讨厌:)首先,您不能再对CONF_FILE1执行grep并查看它是在哪里定义的。
e37o9pze2#
我可能会这样写:
然而,这仍然是大量的代码,但它确实消除了重复,这是一个胜利。
为什么你的日志文件是数字的?如果它们以0开头,数组比哈希更好。如果它们被命名,它们更具有描述性。
s4n0splo3#
0pizxfdo4#
遗憾的是,这是行不通的,原因是在定义函数('constants')之前使用它们,在调用
constant->import
之前计算它们。使用变量是不起作用的,因为use语句是在编译时求值的,而变量的赋值只在运行时完成,所以它们还没有被定义。
我能给予的唯一解决方案是将其拆分为多个
use constant
语句,在这种情况下,两个语句就可以了(一个用于LOG_DIR
和CONF_DIR
,另一个用于其余语句)。jaxagkaj5#
根据你所做的事情,你可能根本不需要常量。大多数情况下,我写的东西是别人用来完成他们的工作的,所以我用一种给其他程序员灵活性的方式来解决这个问题。我把这些东西变成方法:
通过这种方式,我可以很容易地扩展或覆盖内容。
这样做会失去常量折叠的价值,所以你必须考虑它对你有多重要。