In Perl / Moose, can I have two attributes with interdependent default values?

Can I do this in Moose?

package SomeClass; use Moose; has start => ( isa => 'Int', is => 'ro', lazy => 1, default => sub { $_[0]->end }, ); has end => ( isa => 'Int', is => 'ro', lazy => 1, default => sub { $_[0]->start }, ); ... 

In other words, I want two attributes called "start" and "end", and if only one of them is specified, I want the other to be set to the same thing. Not to indicate one of them is a mistake.

Does this interdependent installation work?

+4
source share
2 answers

Yes, if you remove the possibility of infinite recursion by checking that at least one of these values ​​is specified:

 has start => ( ... predicate => 'has_start', ); has end => ( ... predicate => 'has_end', ); sub BUILD { my $self = shift; die "Need to specify at least one of 'start', 'end'!" if not $self->has_start and not $self->has_end; } 

Alternatively, you can defer the check for subusers by default:

 has start => ( ... predicate => 'has_start', default => sub { my $self = shift; die "Need to specify at least one of 'start', 'end'!" if not $self->has_end; $self->end; }, ); has end => ( ... predicate => 'has_end', default => sub { my $self = shift; die "Need to specify at least one of 'start', 'end'!" if not $self->has_start; $self->start; }, ); 
+16
source

Personally, I would use laziness to make sure that I did not fall into infinite recursion:

 has start => ( is => 'ro', isa => 'Int', lazy => 1, default => sub { shift->end }, predicate => 'has_start', ); has end => ( is => 'ro', isa => 'Int', lazy => 1, default => sub { shift->start }, predicate => 'has_end', ); sub BUILD { my $self = shift; die "Need to specify at least one of 'start', 'end'!" unless $self->has_start || $self->has_end; } 
+2
source

Source: https://habr.com/ru/post/1339430/


All Articles