Это, кажется, сделать в соответствии с просьбой ...
{
package MyPackage;
use Moose;
use Types::Standard qw(Maybe Num);
use Types::Numbers qw(NumRange);
has n => (
is => 'rw',
isa => (Maybe[ NumRange[0,100] ])->plus_coercions(Num, sub { undef }),
coerce => 1,
);
}
print MyPackage->new(n => 99)->dump;
print MyPackage->new(n => 100)->dump;
print MyPackage->new(n => 101)->dump;
Update: несколько объяснений ...
Это тип ограничение на число между 0 и 100:
NumRange[0,100]
Подведет с Maybe[...]
позволяет undef
быть принято в качестве значения:
Maybe[ NumRange[0,100] ]
Теперь нам нужно вызвать метод объекта типа ограничения возвращаемого этого выражения. «Очевидный» Maybe[...]->methodname
не будет работать из-за приоритета оператора ->
(он попытается вызвать метод на arrayref и передать результат Maybe
). Поэтому нам нужно предоставить некоторые круглые скобки для вызова метода (Maybe[...])->methodname
.
Метод, который мы будем называть, это plus_coercions
, определенный в Type::Tiny (библиотека ограничений базового типа, используемая обоими типами :: Стандарт и Типы :: Числа). Это создает новый подтип Maybe[NumRange[0,100]]
, но добавляет к нему некоторые принуждения.
Принуждение мы добавляемая:
Num, sub { undef }
... что означает «если значение будет принуждать это число, запустить этот сабвуфер и использовать его выход». В подпункте нам не нужно проверять, является ли принудительное значение за пределами диапазона 0..100, потому что принуждения будут запускаться только в том случае, если значение сбой ограничивает ограничение типа Maybe[NumRange[0,100]]
.
На самом деле, мы могли бы также выразить это так:
(Maybe[ NumRange[0,100] ])->plus_coercions(Num, 'undef')
... используя строку Perl кода вместо суб. Это, возможно, немного менее понятно, но может работать так быстро, потому что это позволяет Type :: Tiny играть в трюки с помощью встроенного кода. (К тому, что я в основном подразумеваю объединение нескольких строк кода Perl и их включение, так что это может привести к тому, что один элемент, который выполняет всю проверку/принуждение, вместо необходимости называть разные субмастеры для проверки и принуждения.)
В этом случае маловероятно, чтобы какая-либо заметная разница в производительности, но если у вас был большой массив таких чисел, которые вы хотели принудить, вы могли бы заметить.
ArrayRef[ (Maybe[NumRange[0,100]])->plus_coercions(Num, 'undef') ]
Можете ли вы привести пример, как это значение не находится между 0 и 100, чтобы установить его в undef?спасибо – smith
Этот ответ может использовать некоторые дополнительные сведения (например, пример * how *, чтобы делать то, что задает OP). В настоящее время это в основном просто ссылка, которая [обескуражена по ряду причин] (http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good -answers). – ThisSuitIsBlackNot