Using separate "use constant" blocks does bypass this problem, but adds a lot of unnecessary code.
It's true?
use constant BASE_PATH => "/etc/app1"; use constant { LOG4PERL_CONF_FILE => BASE_PATH . "/log4perl.conf", CONF_FILE1 => BASE_PATH . "/config1.xml", CONF_FILE2 => BASE_PATH . "/config2.xml", CONF_FILE3 => BASE_PATH . "/config3.xml", CONF_FILE4 => BASE_PATH . "/config4.xml", CONF_FILE5 => BASE_PATH . "/config5.xml", };
I do not see a lot of problems with this. You indicated the base path at only one point, while respecting the DRY principle. If you assign BASE_PATH to an environment variable:
use constant BASE_PATH => $ENV{MY_BASE_PATH} || "/etc/app1";
... then you have a cheap way to reconfigure your constant without having to edit your code. What is not to like there?
If you really want to reduce the repeated concatenation of "BASE_PATH.", You can add some mechanisms for setting constants yourself and not take this into account:
use strict; use warnings; use constant BASE_PATH => $ENV{MY_PATH} || '/etc/apps'; BEGIN { my %conf = ( FILE1 => "/config1.xml", FILE2 => "/config2.xml", ); for my $constant (keys %conf) { no strict 'refs'; *{__PACKAGE__ . "::CONF_$constant"} = sub () {BASE_PATH . "$conf{$constant}"}; } } print "Config is ", CONF_FILE1, ".\n";
But at this moment I think that the balance was thrown from the right to the opposite :) For starters, you can no longer grep for CONF_FILE1 and see where it is defined.
dland
source share