Я нахожу следующий антишаблон повторенным в моих сценариях Perl: сценарий содержит некоторую машину/установку определенные настройки, которые я храню встроенный как константы в сценарии, тогда как остальная часть сценария носит общий характер:
#!/usr/bin/perl
use strict;
use warnings;
# machine specific settings at the start of the script.
my $SETTING_1 = "foo";
my @SETTING_2 = ("123", "456");
my $SETTING_3 = "something";
# general part of script follows.
...
Этот шаблон несколько хорошо при работе одной машины, но как только я хочу распределить сценарий нескольким машинам, проблема запускается, так как я должен отслеживать так, чтобы я не перезаписывал настройки, расстаются с новыми обновлениями в общей части.
Правильное решение состоит в том, чтобы, очевидно, иметь один общий файл сценария и иметь его, считал конфигурационный файл, который характерен для среды, в которой работает сценарий.
Мой вопрос: Какой модуль CPAN Вы рекомендовали бы для решения этой проблемы? Почему?
Мне больше всего нравится Config :: Std . Мне нравится, как он обрабатывает многострочные и многострочные значения конфигурации.
Будьте осторожны, когда переменная потенциально многозначная: если в файле конфигурации существует одно значение, оно сохранит значение в скаляре; если существует несколько значений, вы получите ссылку на массив.
Я считаю удобным иметь два файла конфигурации: один для значений, описывающих операционную среду (где искать библиотеки и т. Д.), А другой для поведения, изменяемого пользователем.
Я также люблю писать вокруг него оболочку. Например (обновлено, чтобы включить автоматически сгенерированные средства доступа только для чтения):
#!/usr/bin/perl
package My::Config;
use strict; use warnings;
use Config::Std;
use FindBin qw($Bin);
use File::Spec::Functions qw( catfile );
sub new {
my $class = shift;
my ($config_file) = @_;
$config_file = catfile($Bin, 'config.ini');
read_config $config_file => my %config;
my $object = bless \%config => $class;
$object->gen_accessors(
single => {
install => [ qw( root ) ],
},
multi => {
template => [ qw( dir ) ],
},
);
return $object;
}
sub gen_accessors {
my $config = shift;
my %args = @_;
my $class = ref $config;
{
no strict 'refs';
for my $section ( keys %{ $args{single} } ) {
my @vars = @{ $args{single}->{$section} };
for my $var ( @vars ) {
*{ "${class}::${section}_${var}" } = sub {
$config->{$section}{$var};
};
}
}
for my $section ( keys %{ $args{multi} } ) {
my @vars = @{ $args{multi}->{$section} };
for my $var ( @vars ) {
*{ "${class}::${section}_${var}" } = sub {
my $val = $config->{$section}{$var};
return [ $val ] unless 'ARRAY' eq ref $val;
return $val;
}
}
}
}
return;
}
package main;
use strict; use warnings;
my $config = My::Config->new;
use Data::Dumper;
print Dumper($config->install_root, $config->template_dir);
C:\Temp> cat config.ini [install] root = c:\opt [template] dir = C:\opt\app\tmpl dir = C:\opt\common\tmpl
Вывод:
C:\Temp> g.pl $VAR1 = 'c:\\opt'; $VAR2 = [ 'C:\\opt\\app\\tmpl', 'C:\\opt\\common\\tmpl' ];
Обычный низкотехнологичный метод - просто выполнить EXPR файл конфигурации. Вы изучали это?
Рискуя быть высмеянным вне класса, одно из решений - сохранить конфигурацию в XML (или, для более смелых, JSON). Потребляемый человеком, совместимый за пределами Perl, не обязательно должен находиться на локальном ПК (XML и JSON могут быть запрошены с помощью «URL-адреса конфигурации») и множества стандартных модулей (XML :: Simple обычно достаточно для config XML-файлы) существуют на CPAN.
Для простой конфигурации, подобной этой, особенно для тривиальных вещей, когда я не ожидаю, что эти данные изменятся в реальном мире, я часто просто использую YAML. Простота не может быть лучше:
Сначала напишите структуру данных на Perl, содержащую вашу конфигурацию.
use YAML;
my $SETTINGS = {
'1' => "foo",
'2' => ["123", "456"],
'3' => "something",
};
Затем передайте ее в YAML::DumpFile();
YAML::DumpFile("~/.$appname.yaml", $SETTINGS);
Удалите структуру данных и замените ее на
my $SETTINGS = YAML::LoadFile("~/.$appname.yaml");
А затем забудьте о ней. Даже если вы не знаете или не хотите изучать синтаксис YAML, небольшие изменения в конфигурации можно сделать вручную, а более серьезные - на Perl, а затем повторно выгрузить в YAML.
Библиотека Config: Properties удобна для чтения и записи файлов свойств пары ключ / значение.
Не привязывайте себя к формату - используйте Config :: Any , или, для немного большего фактора DWIM, Config :: JFDI (который сам является оболочкой для Config :: Any). С ними вы покупаете возможность поддерживать INI, YAML, XML, конфигурацию в стиле Apache и многое другое.
Config :: JFDI основывается на этом, пытаясь уловить некоторые из магических свойств загрузчика конфигурации Catalyst: слияние локальной конфигурации экземпляра с конфигурацией всего приложения, поддержка переменных среды и ограниченные возможности макросов ( __ path_to ( foo / bar) __
на удивление часто пригодится.)
Для конфигурационных файлов мне нравится использовать YAML. Простой, кроссплатформенный, читаемый человеком, и нет опасности, что ваша конфигурация случайно превратится в настоящую программу.
Я предпочитаю YAML и YAML :: XS для данных конфигурации. Он простой, читаемый и привязан практически к любому языку программирования. Другой популярный вариант - Config :: General .