(BTW, this is re: the reimplementation of major chunks of BioPerl
using Moose, Biome: http://github.com/cjfields/biome/tree/)
Locations should use a Role (specifically, Biome::Role::Range), so
start/end/strand should be attributes, not methods. With attributes
the best way to do this is probably with a builder, and lazily (start
requires end, and vice versa). Factor out the common code as Tomas
indicates. BTW, the $self->throw() is akin to BioPerl's $self-
>throw() exception handling; it simply catches any exceptions and
passes them to the metaclass exception handling.
I've been thinking about making the Range role abstract for this very
reason (or defining very basic attributes); something like:
----------------------------
package Bio::Role::Range;
requires qw(_build_start _build_end _build_strand);
# also require other methods which need to be defined in implementation
has 'start' => (
isa => 'Int',
is => 'rw',
builder => '_build_start',
lazy => 1
);
# same for end, strand (except strand has a different isa via
MooseX::Types)
....
package Bio::Location::Foo;
with 'Bio::Role::Range';
sub _build_start {
# for location-specific start
}
sub _build_end {
# for location-specific end
}
sub _build_strand {
# for location-specific strand
}
sub _common_build_method {
# factor out common code here, call from other builders
}
----------------------------
Also, I think the Coordinate-related stuff should be simplified down
to a trait or an attribute; they bring in way too much overhead in
bioperl w/o much added value.
And now back to your regular Moose-related broadcast...
chris
On Aug 11, 2009, at 9:27 PM, Siddhartha Basu wrote:
Hi,
In one my classes i have this boilerplate code block that is
repeated all
over ....
sub start {
my ( $self, $value ) = @_;
$self->{'_start'} = $value if defined $value;
## -- from here
$self->throw( "Only adjacent residues when location type "
. "is IN-BETWEEN. Not ["
. $self->{'_start'}
. "] and ["
. $self->{'_end'}
. "]" )
if defined $self->{'_start'}
&& defined $self->{'_end'}
&& $self->location_type eq 'IN-BETWEEN'
&& ( $self->{'_end'} - 1 != $self->{'_start'} );
return $self->{'_start'};
## -- here
}
then again ....
sub end {
my ( $self, $value ) = @_;
$self->{'_end'} = $value if defined $value;
#assume end is the same as start if not defined
if ( !defined $self->{'_end'} ) {
if ( !defined $self->{'_start'} ) {
$self->warn('Calling end without a defined start
position');
return;
}
$self->warn('Setting start equal to end');
$self->{'_end'} = $self->{'_start'};
}
## ----
$self->throw( "Only adjacent residues when location type "
. "is IN-BETWEEN. Not ["
. $self->{'_start'}
. "] and ["
. $self->{'_end'}
. "]" )
if defined $self->{'_start'}
&& defined $self->{'_end'}
&& $self->location_type eq 'IN-BETWEEN'
&& ( $self->{'_end'} - 1 != $self->{'_start'} );
return $self->{'_end'};
#---------
}
Is there any way moose can be used here for more code resuage. I
thought
about converted it to a type but still couldn't figure out how that
can
be done.
thanks,
-siddhartha