File Coverage

blib/lib/Bio/Gonzales/MiniFeat.pm
Criterion Covered Total %
statement 83 100 83.0
branch 25 34 73.5
condition 13 18 72.2
subroutine 23 31 74.1
pod 0 19 0.0
total 144 202 71.2


line stmt bran cond sub pod time code
1             package Bio::Gonzales::MiniFeat;
2 4     4   2288 use strict;
  4         12  
  4         133  
3 4     4   1477 use warnings;
  4         9  
  4         118  
4 4     4   20 use Carp;
  4         9  
  4         209  
5              
6 4     4   26 use Mouse;
  4         8  
  4         27  
7 4     4   1806 use List::MoreUtils qw/zip/;
  4         9  
  4         63  
8 4     4   2971 use Data::Dumper;
  4         19  
  4         216  
9 4     4   28 use Storable qw(dclone);
  4         9  
  4         223  
10 4     4   27 use Scalar::Util qw/refaddr/;
  4         8  
  4         5846  
11              
12             our $QUIET_MODE;
13              
14             our $VERSION = '0.083'; # VERSION
15              
16             has type => ( is => 'rw', required => 1 );
17             has source => ( is => 'rw' );
18              
19             has attributes => ( is => 'rw', default => sub { {} } );
20              
21             has [qw/subfeats parentfeats/] => ( is => 'rw', default => sub { [] } );
22              
23 79     79 0 339 sub attr { return shift->attributes(@_); }
24              
25             sub clone {
26 0     0 0 0 my ($self) = @_;
27              
28 0         0 my %data = %$self;
29 0 0       0 $data{attributes} = dclone( $data{attributes} ) if ( exists( $data{attributes} ) );
30              
31 0         0 return __PACKAGE__->new( \%data );
32             }
33              
34             sub _attr_single {
35 198     198   382 my ( $self, $p ) = @_;
36 198 50       422 $p = { name => $p } unless ( ref $p );
37              
38 198 50       405 confess "no attributes can be set with this method" if ( $p->{args} );
39             return
40 198 100 66     623 unless ( exists( $self->attributes->{ $p->{name} } ) && @{ $self->attributes->{ $p->{name} } } > 0 );
  176         655  
41             carp "multiple ID entries, taking the first"
42 176 100 100     255 if ( @{ $self->attributes->{ $p->{name} } } > 1 && !$p->{quiet} );
  176         840  
43 176         4240 return $self->attributes->{ $p->{name} }[0];
44             }
45              
46             sub _attr_list {
47 151     151   304 my ( $self, $attr, @values ) = @_;
48              
49             return
50 151 100 66     485 unless ( exists( $self->attributes->{$attr} ) && @{ $self->attributes->{$attr} } > 0 );
  95         330  
51              
52 95 100 66     350 return wantarray ? @{ $self->attributes->{$attr} } : $self->attributes->{$attr}
  60 100       284  
53             unless ( @values && @values > 0 );
54              
55 6         14 my $current_v = $self->attributes->{$attr};
56 6         10 my $new_v;
57 6 50 33     27 if ( @values == 1 && ref $values[0] eq 'ARRAY' ) {
58 6         14 $self->attributes->{$attr} = $values[0];
59             } else {
60 0         0 $self->attributes->{$attr} = \@values;
61              
62             }
63 6 100       26 return wantarray ? @{$current_v} : $current_v;
  2         14  
64             }
65              
66             sub first_attr {
67 27     27 0 61 my ( $self, $name ) = @_;
68 27         100 return $self->_attr_single( { name => $name, quiet => 1 } );
69             }
70              
71 27     27 0 80 sub attr_first { return shift->first_attr(@_); }
72              
73 133     133 0 540 sub id { return shift->_attr_single( { name => 'ID' } ); }
74              
75 92     92 0 190 sub ids { return shift->_attr_list( 'ID', @_ ); }
76              
77 0     0 0 0 sub attr_list { return shift->_attr_list(shift); }
78              
79 38     38 0 105 sub name { return shift->_attr_single( { name => 'Name' } ); }
80              
81 57     57 0 170 sub parent_ids { return shift->_attr_list( 'Parent', @_ ); }
82              
83 0     0 0 0 sub parent_id { return shift->_attr_single( { name => 'Parent' } ); }
84              
85 0     0 0 0 sub attr_replace { return shift->replace_attr(@_) }
86              
87             sub replace_attr {
88 2     2 0 7 my ( $self, $name, @values ) = @_;
89              
90 2 50       6 confess "name cannot be a reference" if ( ref $name );
91 2         7 return $self->_attr_list( $name, @values );
92             }
93              
94             sub parents {
95 0     0 0 0 confess 'use parent_ids';
96             }
97              
98             sub parent {
99 0     0 0 0 confess 'use parent_id';
100             }
101              
102             sub recurse_subfeats {
103 27     27 0 156 my ( $self, $sub ) = @_;
104              
105 36     36   54 $sub = sub { return $_[0] }
106 27 50       93 unless defined $sub;
107              
108 27         36 my %visited;
109 27         61 return $self->_recurse_subfeats( \%visited, $sub, 1 );
110              
111             }
112              
113             sub _recurse_subfeats {
114 63     63   102 my ( $self, $v, $sub, $depth ) = @_;
115              
116 63 100 100     178 if ( exists( $v->{ refaddr($self) } ) && $v->{ refaddr($self) } != $depth ) {
117             confess "Recursion in subfeature retrieval in level $depth/"
118 1         11 . $v->{ refaddr($self) } . "\n"
119             . Dumper $self;
120             }
121              
122 62         160 $v->{ refaddr($self) } = $depth;
123              
124 62         85 my @result;
125 62 100       76 if ( @{ $self->subfeats } > 0 ) {
  62         166  
126 11         14 $depth++;
127 11         40 for my $sf ( @{ $self->subfeats } ) {
  11         28  
128 36         65 push @result, $sub->( $sf, $depth );
129 36         69 push @result, $sf->_recurse_subfeats( $v, $sub, $depth );
130             }
131             }
132              
133 60         159 return @result;
134             }
135              
136             sub uniq {
137 57     57 0 79 my ($self) = @_;
138              
139 57         76 $self->subfeats( [ List::MoreUtils::uniq @{ $self->subfeats } ] );
  57         242  
140 57         97 $self->parentfeats( [ List::MoreUtils::uniq @{ $self->parentfeats } ] );
  57         187  
141             }
142              
143             sub add_attr {
144 440     440 0 1136 my ( $self, %attrs ) = @_;
145              
146 440         1351 while ( my ( $name, $value ) = each %attrs ) {
147 440 100       1473 $self->attributes->{$name} = [] unless defined $self->attributes->{$name};
148 440 100       627 push @{ $self->attributes->{$name} }, ( ref $value eq 'ARRAY' ? @$value : $value );
  440         2259  
149             }
150              
151 440         1286 return;
152             }
153              
154             sub has_attr {
155 0     0 0   my ( $self, $name ) = @_;
156 0           return exists( $self->attributes->{$name} );
157             }
158              
159             sub del_attr {
160 0     0 0   my ( $self, @names ) = @_;
161              
162 0           my @deleted;
163 0           for my $name (@names) {
164 0           push @deleted, delete $self->attributes->{$name};
165             }
166 0 0         return @names == 1 ? $deleted[0] : \@deleted;
167             }
168              
169             1;