2 # BioPerl module for Bio::Annotation::StructuredValue
4 # Please direct questions and support issues to <bioperl-l@bioperl.org>
6 # Cared for by Hilmar Lapp <hlapp at gmx.net>
8 # (c) Hilmar Lapp, hlapp at gmx.net, 2002.
9 # (c) GNF, Genomics Institute of the Novartis Research Foundation, 2002.
11 # You may distribute this module under the same terms as perl itself.
12 # Refer to the Perl Artistic License (see the license accompanying this
13 # software package, or see http://www.perl.com/language/misc/Artistic.html)
14 # for the terms under which you may use, modify, and redistribute this module.
16 # THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
17 # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
18 # MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 # POD documentation - main docs before the code
24 Bio::Annotation::StructuredValue - A scalar with embedded structured
29 use Bio::Annotation::StructuredValue;
30 use Bio::Annotation::Collection;
32 my $col = Bio::Annotation::Collection->new();
33 my $sv = Bio::Annotation::StructuredValue->new(-value => 'someval');
34 $col->add_Annotation('tagname', $sv);
38 Scalar value annotation object.
44 User feedback is an integral part of the evolution of this and other
45 Bioperl modules. Send your comments and suggestions preferably to one
46 of the Bioperl mailing lists. Your participation is much appreciated.
48 bioperl-l@bioperl.org - General discussion
49 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
53 Please direct usage questions or support issues to the mailing list:
55 I<bioperl-l@bioperl.org>
57 rather than to the module maintainer directly. Many experienced and
58 reponsive experts will be able look at the problem and quickly
59 address it. Please include a thorough description of the problem
60 with code and data examples if at all possible.
64 Report bugs to the Bioperl bug tracking system to help us keep track
65 the bugs and their resolution. Bug reports can be submitted via
68 https://github.com/bioperl/bioperl-live/issues
70 =head1 AUTHOR - Hilmar Lapp
72 Email hlapp-at-gmx.net
76 The rest of the documentation details each of the object methods. Internal methods are usually preceded with a _
81 # Let the code begin...
84 package Bio
::Annotation
::StructuredValue
;
87 # Object preamble - inherits from Bio::Root::Root
89 use base
qw(Bio::Annotation::SimpleValue);
94 Usage : my $sv = Bio::Annotation::StructuredValue->new();
95 Function: Instantiate a new StructuredValue object
96 Returns : Bio::Annotation::StructuredValue object
97 Args : -value => $value to initialize the object data field [optional]
98 -tagname => $tag to initialize the tagname [optional]
103 my ($class,@args) = @_;
105 my $self = $class->SUPER::new
(@args);
107 my ($value,$tag) = $self->_rearrange([qw(VALUE TAGNAME)], @args);
108 $self->{'values'} = [];
109 defined $value && $self->value($value);
110 defined $tag && $self->tagname($tag);
116 =head1 AnnotationI implementing functions
123 Usage : my $text = $obj->as_text
124 Function: return the string "Value: $v" where $v is the value
134 return "Value: ".$self->value;
140 Usage : my $str = $ann->display_text();
141 Function: returns a string. Unlike as_text(), this method returns a string
142 formatted as would be expected for te specific implementation.
144 One can pass a callback as an argument which allows custom text
145 generation; the callback is passed the current instance and any text
149 Args : [optional] callback
154 my $DEFAULT_CB = sub { $_[0]->value || ''};
157 my ($self, $cb) = @_;
159 $self->throw("Callback must be a code reference") if ref $cb ne 'CODE';
168 Usage : my $hashtree = $value->hash_tree
169 Function: For supporting the AnnotationI interface just returns the value
170 as a hashref with the key 'value' pointing to the value
181 $h->{'value'} = $self->value;
187 Usage : $obj->tagname($newval)
188 Function: Get/set the tagname for this annotation value.
190 Setting this is optional. If set, it obviates the need to provide
191 a tag to AnnotationCollection when adding this object.
193 Returns : value of tagname (a scalar)
194 Args : new value (a scalar, optional)
200 my ($self,$value) = @_;
201 if( defined $value) {
202 $self->{'tagname'} = $value;
204 return $self->{'tagname'};
208 =head1 Specific accessors for StructuredValue
215 Usage : $obj->value($newval)
216 Function: Get/set the value for this annotation.
218 Set mode is here only to retain compatibility with
219 SimpleValue. It is equivalent to calling
220 add_value([0], $newval).
222 In get mode, this implementation allows one to pass additional
223 parameters that control how the structured annotation
224 components will be joined together to form a
225 string. Recognized are presently
226 -joins a reference to an array of join strings, the
227 elements at index i applying to joining
228 annotations at dimension i. The last element
229 will be re-used for dimensions higher than i.
231 -brackets a reference to an array of two strings
232 denoting the opening and closing brackets for
233 the elements of one dimension, if there is
234 more than one element in the dimension.
235 Defaults to ['(',')'].
237 Returns : value of value
238 Args : newvalue (optional)
244 my ($self,$value,@args) = @_;
247 return $self->add_value([0], $value) if defined($value) && (@args == 0);
249 # determine joins and brackets
250 unshift(@args, $value);
251 my ($joins, $brackets) =
252 $self->_rearrange([qw(JOINS BRACKETS)], @args);
253 $joins = ['; '] unless $joins;
254 $brackets = ['(', ')'] unless $brackets;
255 my $txt = &_to_text
($self->{'values'}, $joins, $brackets);
256 # if there's only brackets at the start and end, remove them
257 if((@
{$self->{'values'}} == 1) &&
258 (length($brackets->[0]) == 1) && (length($brackets->[1]) == 1)) {
259 my $re = '\\'.$brackets->[0].
260 '([^\\'.$brackets->[1].']*)\\'.$brackets->[1];
267 my ($arr, $joins, $brackets, $rec_n) = @_;
269 $rec_n = 0 unless defined($rec_n);
270 my $i = $rec_n >= @
$joins ? @
$joins-1 : $rec_n;
271 my $txt = join($joins->[$i],
274 (ref($_) eq "ARRAY" ?
275 &_to_text
($_, $joins, $brackets, $rec_n+1) :
279 if($rec_n && (@
$arr > 1)) {
280 $txt = $brackets->[0] . $txt . $brackets->[1];
289 Function: Get the top-level array of values. Each of the elements will
290 recursively be a reference to an array or a scalar, depending
291 on the depth of this structured value annotation.
302 return @
{$self->{'values'}};
305 =head2 get_all_values
307 Title : get_all_values
309 Function: Flattens all values in this structured annotation and
310 returns them as an array.
312 Returns : the (flat) array of values
320 # we code lazy here and just take advantage of value()
321 my $txt = $self->value(-joins
=> ['@!@'], -brackets
=> ['','']);
322 return split(/\@!\@/, $txt);
329 Function: Adds the given value to the structured annotation at the
332 The index is multi-dimensional, with the first dimension
333 applying to the first level, and so forth. If a particular
334 dimension or a particular index does not exist yet, it will
335 be created. If it does exist and adding the value would
336 mean replacing a scalar with an array reference, we throw
337 an exception to prevent unintended damage. An index of -1
338 at any dimension means append.
340 If an array of values is to be added, it will create an
341 additional dimension at the index specified, unless the
342 last index value is -1, in which case they will all be
343 appended to the last dimension.
347 Args : the index at which to add (a reference to an array)
354 my ($self,$index,@values) = @_;
356 my $tree = $self->{'values'};
357 my $lastidx = pop(@
$index);
358 foreach my $i (@
$index) {
361 push(@
$tree, $subtree);
363 } elsif((! $tree->[$i]) || (ref($tree->[$i]) eq "ARRAY")) {
364 $tree->[$i] = [] unless ref($tree->[$i]) eq "ARRAY";
367 $self->throw("element $i is a scalar but not in last dimension");
371 push(@
$tree, @values);
372 } elsif(@values < 2) {
373 $tree->[$lastidx] = shift(@values);
375 $tree->[$lastidx] = [@values];