2013-05-27 56 views
7

利用穆斯的屬性,它可以創建一個具有默認值的屬性。 我有一組都有一個最小,最大和默認值的屬性。 它們是代表比例的屬性(如Tk :: Scale)。Perl的駝鹿最小值,最大值和默認值

目前,我至少有3個屬性: 當前&默認:

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

分鐘:

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

最大:

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

是否possioble有四個(當前,默認,最小,最大)在一個屬性?

回答

7

我想你想創建一個驗證規則。

use Moose::Util::TypeConstraints; 

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

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

這看起來不錯。有沒有辦法檢查屬性?例如。從中獲取最小值,最大值和默認值? – capfan

+1

AFAIK不與Moose :: Meta :: TypeConstraint。您可以不創建子類型,而是創建一個包類來封裝此功能,並將使用min,max屬性包裝子類型。 – snoofkin

+0

@ikegami請告訴我在哪裏可以讀到關於穆斯類課程的內容?附帶麋發行 – gaussblurinc

1

當然有很多的方法來一堆值組合成更復雜的價值 - 這基本上是數據結構的研究是關於。選擇哪些特定的數據結構是一個相當複雜的問題,高度依賴於您的實際使用情況。

我心中有數一點關於你的情況,但我已經從你的問題收集到的東西,所有這些屬性都代表同樣結構的概念。因此,我將創建一個新的數據類型,Scale

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); 
    } 
} 

而且我會在一些ThingWithScale是由一個Scale對象支持目前的屬性。

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); 

而關於我寫的是BUILDARGS方法來自動實例從簡單的構造函數的參數的秤對象,我會意識到的時候我真正想要做的是創造一種新的屬性trait描述屬性,這些屬性具有最低和最高法定價值。