Я работаю с Moose
пакетами в Perl, которые используют MooseX::Params::Validate
для определения интерфейса. Эти интерфейсы, как правило, довольно гибкие и позволяют использовать несколько необязательных параметров. К сожалению, это Perl, поэтому типы возвращаемых данных будут меняться в зависимости от дополнительных параметров, и есть преимущество для передачи необязательных параметров в большинстве случаев, когда они определены в вызывающем. Различные методы, экспортируемые из MooseX::Params::Validate
, используются в этой кодовой базе, поэтому из-за различных способов обработки пакета undef
параметры, которые я не могу передать, будут в любом случае изящными. Я, как правило, использую следующий метод, но в обзорах это очень много, и я хотел бы спросить, есть ли другой способ достичь этой гибкости.Условный параметр, передаваемый с MooseX :: Params :: Validate
use strict;
use warnings;
my $bar;
Foo->foo({
foo => 'I, Foo need a VERY flexible interface. ',
$bar ? (bar => $bar) :()
});
$bar = "Very flexible...";
Foo->foo({
foo => 'I, Foo need a VERY flexible interface. ',
$bar ? (bar => $bar) :()
});
package Foo;
use Moose;
use MooseX::Params::Validate;
sub foo {
my $self = shift;
my ($foo, $bar) = validated_list(
\@_,
foo => { isa => 'Str' },
bar => { isa => 'Str', optional => 1 },
);
print $foo . $bar . "\n";
}
1;
Тройная оператор, чтобы проверить переменные defined
состояния является то, что всегда оставляет меня, желая вариант пАРАМЕТР //
типа, но я не могу увидеть где-нибудь этот тип операции поддерживается.
Ответы для caller
предпочтительнее, так как я не хочу (не будет) изменять интерфейс различных пакетов, но я открыт для ответов, показывающих методы обработки undef
значений параметров, передаваемых также.
Для абонентов, ваш "идиома" кажется laborous [и, что более важно, к ошибкам]. Как насчет замены тройной с более простой вспомогательной функцией, например: 'sub defme {my (@arr); push (@arr, $ _ [0], $ _ [1]), если ($ _ [1]); @arr; } '? Затем у вас есть 'defme (" bar ", $ bar)' вместо тройной. Или, в конструкторе, делайте '//' или '// =' при необходимости _before_ вызывая 'validated_list', так как первый arg всегда указывает на temp? –
@CraigEstey вы можете объяснить, насколько более склонны к ошибкам и кропотливости (я был в основном обеспокоен читабельностью) и как работает ваше решение, потому что я не вижу, как это применимо? – MattSizzle
Моя функция AFAICT делает то, что делает trernary - создает массив, который либо заполняется символом '($ sym, $ val)', либо пустым. И, IMO, 'defme (« bar », $ bar)' более читабельна, чем [более длинная] '$ bar? (bar => $ bar):() '. Вызов fnc короче и проще троичного синтаксиса. И, при необходимости, вы можете добавить debug printfs в fnc. Но, вероятно, лучше всего, чтобы все вызывающие абоненты просто делали '(bar => $ var)' и позволяли 'foo' справляться с этим, а не возлагать ответственность на вызывающих. Даже если вы все еще хотите тройной, 'foo' все равно нуждается в защите, так или иначе. Итак, если проверить, почему бы и не исправить? –