Почему бы не передать запрашиваемую блокировку непосредственно самому запросу?
MyEntity entity = entityManager.find(MyEntity.class, key, LockModeType.PESSIMISTIC_WRITE);
Насколько я понимаю, это делает именно то, что вы хотели. ( документация )
Я, вероятно, записал бы это как это:
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;
Однако это - все еще много кода, но он действительно удаляет дублирование, и это - победа.
Почему Ваши файлы журнала являются числовыми? Если они запускают с 0, массив является лучшим выбором, чем хеш. Если их называют, они являются более описательными.
Используя отдельное "использование постоянные" блоки делают обходное решение эта проблема, но это добавляет много ненужного кода.
Он действительно?
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",
};
Я не вижу много проблем с этим. Вы указали основной путь в одной точке только, таким образом, соблюдя принцип DRY. Если Вы присваиваете BASE_PATH с переменной среды:
use constant BASE_PATH => $ENV{MY_BASE_PATH} || "/etc/app1";
... у Вас затем есть дешевый способ реконфигурировать Вашу константу, не имея необходимость редактировать Ваш код. Что там для не симпатии приблизительно этого?
Если Вы действительно хотите сократить повторяющийся "BASE_PATH". конкатенация, Вы могли добавить немного оборудования для установки констант сами и фактора что далеко:
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";
Но в этой точке я думаю, что баланс колебался далеко от Корректного до Противного :) Для запуска Вы больше не можете grep для CONF_FILE1 и видеть, где он определяется.
use constant +{
map { sprintf $_, '/var/log' } (
LOG_DIR => "%s/",
LOG_FILENAME => "%s/file1.log",
),
map { sprintf $_, '/etc/app1' } (
LOG4PERL_CONF_FILE => "%s/log4perl.conf",
CONF_FILE1 => "%s/config1.xml",
CONF_FILE2 => "%s/config2.xml",
CONF_FILE3 => "%s/config3.xml",
CONF_FILE4 => "%s/config4.xml",
CONF_FILE5 => "%s/config5.xml",
),
};
Это не собирается работать, печально. Причина этого состоит в том, что Вы используете функции ('константы'), прежде чем они будут определены. Вы оцениваете их перед вызовом к constant->import
.
Используя переменные не работает, потому что операторы использования оценены во время компиляции. Присвоение переменным только сделано во времени выполнения, таким образом, они еще не будут определены.
Единственное решение, которое я могу дать, состоит в том, чтобы разделить его на несколько use constant
операторы. В этом случае два оператора сделают (один для LOG_DIR
и CONF_DIR
, другой для остальных).
В зависимости от того, что Вы делаете, Вы не могли бы хотеть константы вообще. Главным образом я пишу материал, который другие люди используют, чтобы сделать их материал, таким образом, я решаю эту проблему способом, которая дает другую гибкость программистов. Я превращаю эти вещи в методы:
sub base_log_dir { '...' }
sub get_log_file
{
my( $self, $number ) = @_;
my $log_file = catfile(
$self->base_log_dir,
sprintf "foo%03d", $number
);
}
Путем выполнения его этот путь я могу легко расширить или переопределить вещи.
Выполнение этого теряет значение сворачивания констант, хотя, таким образом, необходимо думать о том, как важный, который является Вам.