Я делаю вот так.
Объявляем хеш, со значениями из конфига. Часть значений у меня обязательны и могут быть дефолтными, часть добавится потом, если указаны в конфиге.
my %component_config = (
# Если не получилось подключить конфиг, эта переменная указывает на то, что мы используем значения по умолчанию.
default => '1',
debug => '1',
logfile => 'stdout',
);
Читаем конфиг. В качестве аргументов принимает путь к файлу конфига и ссылку на хеш, который будет заполняться значениями из конфига. Комментарии в конфиге начинаются с решётки и игнорируются. Пустые строки, лишние пробелы и т.д. тоже. После окончания работы функции получаем хеш, заполненный значениями из конфига.
sub fill_config {
my $configfile = $_[0];
return 0 unless open(SOURCE, "< $configfile");
# Раз мы продолжаем работать, значит конфиг удачно прочитался и настройки не дефолтные.
$_[1]{default} = 0;
while (<SOURCE>) {
chomp;
s/(#.*|^\s+|\s+$)//g;
next unless length;
my ($var, $value) = split(/\s*=\s*/, $_, 2);
$_[1]{$var} = $value;
}
close(SOURCE);
return 1;
}
Таким образом одна и та же функция позволяет читать какие угодно конфиги в рамках программы(у меня софтинка с множеством автоподключаемых модулей, и у каждого из них может быть свой конфиг).
У меня свой парсер ini-like файлов - 100 строк кода всего навсего. Минусы eval - можно зафигачить system(«rm -rf»). Минусы json - свалится при кривом синтаксисе (надо приличное время тюнинговать по себя).