2013-05-27 18 views
7

Moose kullanılarak, varsayılan değere sahip öznitelikler oluşturmak mümkündür. Hepsinin minimum, maksimum ve varsayılan değeri olan bir dizi özellik var. Bunlar bir ölçeği temsil eden niteliklerdir (Tk :: Scale gibi).Perl Moose öznitelikleri minimum, maksimum ve varsayılan değer

Şu anda, en az 3 özelliklere sahiptir: akım & varsayılan:

has 'attr' => (is => 'rw', isa => 'Int', default => 300, lazy => 1, clearer => '_clear_attr'); 

dakika:

has 'attr_min' => (is => 'rw', isa => Int', default => 100); 

max:

has 'attr_max' => (is => 'rw', isa => Int', default => 1000); 

o possioble dördü birden mı bir öznitelikte (geçerli, varsayılan, min, maks)?

cevap

7

Sanırım bir doğrulama kuralı oluşturmak istiyorsunuz.

use Moose::Util::TypeConstraints; 

subtype 'ScaleVal', 
    as 'Int', 
    where { 100 <= $_ && $_ <= 1000 }; 

has attr => (
    is  => 'rw', 
    isa  => 'ScaleVal', 
    default => 300, 
); 
+0

Bu güzel görünüyor. Özniteliği incelemek için herhangi bir yolu var mı? Örneğin. min, max ve ondan varsayılan değer olsun? – capfan

+1

AFAIK, Moose :: Meta :: TypeConstraint ile değil. Bir alt tür oluşturmak yerine, bu işlevselliği kapsamaya yarayan bir paket sınıfı oluşturabilir ve min, max öznitelikleriyle bir alt türünü kapatabilirsiniz. – snoofkin

+0

@ikegami lütfen, Moose sınıf sistemini nerede okuyabilirim? – gaussblurinc

1

daha karmaşık bir değer haline değerlerin bir demet birleştirmek için pek çok yolu elbette vardır - bu veri yapılarının çalışma hakkında ne temelde. Seçeceğiniz belirli veri yapıları, gerçek kullanım durumlarınıza büyük ölçüde bağımlı olan, oldukça ilgili bir sorudur.

Sizin durumunuz hakkında oldukça az şey biliyorum, ama bu özelliklerin hepsinin benzer şekilde yapılandırılmış kavramları temsil ettiğinden, sorularınızdan aldığım şey. Ve bu yüzden yeni bir veri türü, Scale yaratacak:

use MooseX::Declare; 
class Scale { 
    for (qw/min max def/) { 
     has $_ => (is => 'ro', isa => 'Num', required => 1); 
    } 
    has val => (is => 'rw', isa => 'Num', lazy_build => 1); 
    method _build_val() { 
     return $self->def; 
    } 
    method BUILD($args) { 
     confess "Out of range!" unless $self->_is_in_range($self->val); 
    } 
    method _is_in_range($val) { 
     return defined $val && $val >= $self->min && $val <= $self->max; 
    } 
    before val ($new_val?) { 
     return unless defined $new_val; 
     confess "Out of range!" unless $self->_is_in_range($new_val); 
    } 
} 

Ve ben bir Scale nesne tarafından desteklenen bazı ThingWithScale üzerinde özelliklerini sunacak.

class ThingWithScale { 
    has _attr => (
     is => 'ro', isa => 'Scale', 
     default => sub { shift->_make_attr() }, 
    ); 
    method _make_attr($class: $val?) { 
     return Scale->new(
      min => 100, max => 1000, def => 200, 
      (defined $val ? (val => $val) :()), 
     ) 
    } 
    # Convert `attr` argument to a `Scale` object before passing to real constructor. 
    sub BUILDARGS { 
     my ($class, %args) = @_; 

     if (defined (my $attr = delete $args{attr})) { 
      %args = (
       %args, 
       _attr => $class->_make_attr($attr) 
      ); 
     } 
     return $class->SUPER::BUILDARGS(%args); 
    } 
} 

my $thing = ThingWithScale->new(attr => 101); 

Ve

ne gerçekten yapmak istediğim özelliklerini tanımlamak için yeni bir özellik trait icat etmek olduğunu otomatik olarak basit yapıcı parametresinden bir Ölçek nesne örneğini oluşturmak için BUILDARGS yöntem, fark edeceğini yazdığı zaman hakkında o asgari ve azami yasal değerlere sahipti.

İlgili konular