如何减少常量的重复?
我有这个 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 {
LOG_DIR => "/var/log/",
FILE_FILENAME => LOG_DIR . "file1.log"
};
不起作用。
使用单独的“使用常量”块确实可以解决此问题,但这会添加大量不需要的代码。
这样做的正确方法是什么?
I have this Perl script with many defined constants of configuration files. For example:
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",
};
I want to reduce duplication of "/etc/app1" and "/var/log" , but using variables does not work. Also using previously defined constants does not work in the same "use constant block". For example:
use constant {
LOG_DIR => "/var/log/",
FILE_FILENAME => LOG_DIR . "file1.log"
};
does not work.
Using separate "use constant" blocks does workaround this problem, but that adds a lot of unneeded code.
What is the correct way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
根据您所做的事情,您可能根本不需要常量。 大多数情况下,我编写的东西是其他人用来完成他们的工作的,所以我以一种为其他程序员提供灵活性的方式解决这个问题。 我将这些东西变成方法:
通过这样做,我可以轻松地扩展或重写东西。
但这样做会失去不断折叠的价值,所以你必须考虑这对你来说有多重要。
Depending on what you are doing, you might not want constants at all. Mostly, I write stuff that other people use to get their stuff done, so I solve this problem in a way that gives other programmers flexibility. I make these things into methods:
By doing it this way, I can easily extend or override things.
Doing this loses the value of constant folding though, so you have to think about how important that is to you.
遗憾的是,这是行不通的。 原因是您在定义函数(“常量”)之前使用它们。 您可以在调用
constant->import
之前评估它们。使用变量不起作用,因为 use 语句是在编译时评估的。 分配给变量仅在运行时完成,因此它们还没有被定义。
我能给出的唯一解决方案是将其拆分为多个
useconstant
语句。 在这种情况下,需要两条语句(一条用于LOG_DIR
和CONF_DIR
,另一条用于其余部分)。That's not going to work, sadly. The reason for this is that you are using functions ('constants') before they are defined. You evaluate them before the call to
constant->import
.Using variables doesn't work because use statements are evaluated at compile time. Assigning to variables is only done at runtime, so they won't be defined yet.
The only solution I can give is to split it into multiple
use constant
statements. In this case, two statements will do (one forLOG_DIR
andCONF_DIR
, another for the rest).我可能会这样写:
然而,这仍然是很多代码,但它确实消除了重复,这是一个胜利。
为什么你的日志文件是数字的? 如果它们以 0 开头,则数组是比哈希更好的选择。 如果它们被命名,它们就更具描述性。
I'd probably write it like this:
However, that's still a lot of code, but it does remove the duplication and that's a win.
Why are your logfiles numeric? If they start with 0, an array is a better choice than a hash. If they're named, they're more descriptive.
真的吗?
我认为这没有太多问题。 您仅在一点指定了基本路径,从而遵守了 DRY 原则。 如果您为 BASE_PATH 分配一个环境变量:
...那么您就有一种廉价的方法来重新配置常量,而无需编辑代码。 这有什么不喜欢的呢?
如果你真的想减少重复的“BASE_PATH”串联,你可以添加一些机制来自己安装常量并将其分解:
但在这一点上,我认为平衡已经从正确转向了讨厌:)一开始,您不能再 grep 查找 CONF_FILE1 并查看它的定义位置。
Does it really?
I don't see a lot of problems with this. You have specified the base path in one point only, thereby respecting the DRY principle. If you assign BASE_PATH with an environment variable:
... you then have a cheap way of reconfiguring your constant without having to edit your code. What's there to not like about this?
If you really want to cut down the repetitive "BASE_PATH . " concatenation, you could add a bit of machinery to install the constants yourself and factor that away:
But at this point I think the balance has swung away from Correct to Nasty :) For a start, you can no longer grep for CONF_FILE1 and see where it is defined.