Istnieje oczywiście wiele sposobów, aby połączyć kilka wartości w bardziej złożonej wartości - to w zasadzie co badanie struktur danych na temat. Jakie konkretne struktury danych do wyboru to dość wciągające pytanie, wysoce zależne od rzeczywistych przypadków użycia.
Znam dość mało na temat twojej sprawy, ale to, co wyciągnąłem z twojego pytania, że wszystkie te cechy reprezentują podobnie skonstruowane pojęcia. A więc chciałbym utworzyć nowy typ danych, 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);
}
}
i chciałbym przedstawić na jakimś ThingWithScale
atrybuty, które zostały poparte Scale
obiektu.
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);
A o czasie pisałem że BUILDARGS
sposób, aby automatycznie instancję obiektu skala od prostego parametru konstruktora, to zdaję sobie sprawę, że to, co naprawdę chciałem zrobić, to wymyślić nowy atrybut trait opisać atrybuty miały minimalne i maksymalne wartości prawne.
To wygląda dobrze. Czy istnieje sposób sprawdzenia atrybutu? Na przykład. uzyskać wartość minimalną, maksymalną i domyślną? – capfan
AFAIK nie z Moose :: Meta :: TypeConstraint. Zamiast tworzenia podtypu można utworzyć klasę pakietu, aby zaaplikować tę funkcję i zawijać podtyp z atrybutami min, max. – snoofkin
@ikegami, proszę, powiedz, gdzie mogę przeczytać o systemie klasy Moose? – gaussblurinc