Of course, there are many ways to combine a bunch of values ββinto a more complex value - mainly regarding the study of data structures. Which specific data structures to choose is a rather complicated question, highly dependent on your actual use cases.
I know quite a bit about your case, but what I learned from your question is that all these attributes are similarly structured concepts. And so I would create a new data type, 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); } }
And I would introduce the attributes on some ThingWithScale that was supported by the Scale object.
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) : ()), ) }
And around the time I was writing this BUILDARGS method to automatically instantiate a Scale object from a simple constructor parameter, I would understand that what I really wanted to do was invent a new trait attribute to describe the attributes with the minimum and maximum legal values.
darch
source share