На самом деле я выбрал другой подход; для моего приложения полезно иметь возможность напрямую назначать поле фактического типа (поскольку мы разрабатываем функцию, с помощью которой вы можете «обнаружить» команды, которые принимают аргументы различных типов, поэтому наличие поля фактического типа делает это обратный поиск проще).
Итак, я сделал это:
static class DoubleConverter implements ITypeConverter<Double> {
public Double convert(String value) throws Exception {
if(value.isEmpty()) return Double.NaN; // this is a special value that indicates the option was present without a value
return Double.valueOf(value);
}
}
@Option(names = {"-e", "--epsilon"}, arity="0..1", description="Acceptable values: [0, 1] default: 0.1", converter=DoubleConverter.class)
Double epsilon;
По сути, я использую преобразователь для хранения специального значения (в данном случае NaN, потому что в итоге мы использовали двойное), чтобы указать, что параметр присутствует без значения (что отличается от его отсутствия вообще, и в этом случае будет нуль).
Затем проверка и другое поведение выполняются в методе run()
, как вы предложили:
@Override
public void run() {
// null indicates the option was not present, so do nothing
if(epsilon != null) {
// NaN indicates the option was present but with no value, which means we should print the current value
if(epsilon.equals(Double.NaN)) {
// print current value from the application
printEpsilonValue();
}
else {
// validate value
if(epsilon < 0.0 || epsilon > 1.0) {
throw new ParameterException(spec.commandLine(), "Invalid parameter value");
} else {
// set the value in the application
setEpsilonValue(episilon);
}
}
}
}
Я не смог указать значение по умолчанию в описании с помощью переменной, потому что фактическое значение по умолчанию в этом случае должно быть нулевым. Впрочем, это незначительная жертва.
Я понимаю, что это необычный случай, но было бы неплохо поддерживать такую опцию (не логическую с арностью 0..n) без необходимости прибегать к специальным значениям. Возможно, возможность указать другое поле, которое будет служить логическим значением, указывающим, присутствовала ли опция или нет. Тогда не было бы необходимости и в пользовательском преобразователе, и, возможно, все еще можно было бы указать значение по умолчанию (т. е. поле Double в этом случае было бы установлено по умолчанию, но если параметр не присутствовал, соответствующее логическое поле было бы быть ложным, чтобы приложение знало, что не следует использовать значение Double).
person
marinier
schedule
21.09.2018