2013-12-20 4 views
4

Я следующий propertiy на классе МусаМус и constriant класса переменных

package myPackage; 
use Moose; 

has Number => (
    is => 'rw', 
    isa => Num, 

); 

есть вариант с Moose для тягот этого типа плавать число от 0то 100, и если кто-то попытается вставить номер не на диапазоне 0 -100, тогда значение будет undef, если да, как я могу это достичь?

ответ

5

Это, кажется, сделать в соответствии с просьбой ...

{ 
    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') ] 
-3

Да. Обратитесь к документации TypeConstraints и о том, как принудительно использовать значение.

http://metacpan.org/pod/Moose::Util::TypeConstraints

+1

Можете ли вы привести пример, как это значение не находится между 0 и 100, чтобы установить его в undef?спасибо – smith

+3

Этот ответ может использовать некоторые дополнительные сведения (например, пример * how *, чтобы делать то, что задает OP). В настоящее время это в основном просто ссылка, которая [обескуражена по ряду причин] (http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good -answers). – ThisSuitIsBlackNot