Search code examples
perlconstants

How can I reduce duplication in constants?


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?


Solution

  • I'd probably write it like this:

    use Readonly;
    
    Readonly my $LOG_DIR            => "/var/log";
    Readonly my $LOG_FILENAME       => "$LOG_DIR/file1.log";
    Readonly my $ETC                => '/etc/app1';
    Readonly my $LOG4PERL_CONF_FILE => "$ETC/log4perl.con";
    
    # hash because we don't have an index '0'
    Readonly my %CONF_FILES => map { $_ => "$ETC/config$_.xml" } 1 .. 5;
    

    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.