3 # BioPerl module for Bio::Annotation::StructuredValue
5 # Cared for by Hilmar Lapp <hlapp at gmx.net>
7 # (c) Hilmar Lapp, hlapp at gmx.net, 2002.
8 # (c) GNF, Genomics Institute of the Novartis Research Foundation, 2002.
10 # You may distribute this module under the same terms as perl itself.
11 # Refer to the Perl Artistic License (see the license accompanying this
12 # software package, or see http://www.perl.com/language/misc/Artistic.html)
13 # for the terms under which you may use, modify, and redistribute this module.
15 # THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
16 # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
17 # MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 # POD documentation - main docs before the code
23 Bio::Annotation::StructuredValue - A scalar with embedded structured
28 use Bio::Annotation::StructuredValue;
29 use Bio::Annotation::Collection;
31 my $col = Bio::Annotation::Collection->new();
32 my $sv = Bio::Annotation::StructuredValue->new(-value => 'someval');
33 $col->add_Annotation('tagname', $sv);
37 Scalar value annotation object.
43 User feedback is an integral part of the evolution of this and other
44 Bioperl modules. Send your comments and suggestions preferably to one
45 of the Bioperl mailing lists. Your participation is much appreciated.
47 bioperl-l@bioperl.org - General discussion
48 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
52 Report bugs to the Bioperl bug tracking system to help us keep track
53 the bugs and their resolution. Bug reports can be submitted via
56 http://bugzilla.open-bio.org/
58 =head1 AUTHOR - Hilmar Lapp
60 Email hlapp-at-gmx.net
64 The rest of the documentation details each of the object methods. Internal methods are usually preceded with a _
69 # Let the code begin...
72 package Bio
::Annotation
::StructuredValue
;
75 # Object preamble - inherits from Bio::Root::Root
78 use base
qw(Bio::Annotation::SimpleValue);
83 Usage : my $sv = Bio::Annotation::StructuredValue->new();
84 Function: Instantiate a new StructuredValue object
85 Returns : Bio::Annotation::StructuredValue object
86 Args : -value => $value to initialize the object data field [optional]
87 -tagname => $tag to initialize the tagname [optional]
92 my ($class,@args) = @_;
94 my $self = $class->SUPER::new
(@args);
96 my ($value,$tag) = $self->_rearrange([qw(VALUE TAGNAME)], @args);
97 $self->{'values'} = [];
98 defined $value && $self->value($value);
99 defined $tag && $self->tagname($tag);
105 =head1 AnnotationI implementing functions
112 Usage : my $text = $obj->as_text
113 Function: return the string "Value: $v" where $v is the value
123 return "Value: ".$self->value;
129 Usage : my $str = $ann->display_text();
130 Function: returns a string. Unlike as_text(), this method returns a string
131 formatted as would be expected for te specific implementation.
133 One can pass a callback as an argument which allows custom text
134 generation; the callback is passed the current instance and any text
138 Args : [optional] callback
143 my $DEFAULT_CB = sub { $_[0]->value || ''};
146 my ($self, $cb) = @_;
148 $self->throw("Callback must be a code reference") if ref $cb ne 'CODE';
157 Usage : my $hashtree = $value->hash_tree
158 Function: For supporting the AnnotationI interface just returns the value
159 as a hashref with the key 'value' pointing to the value
170 $h->{'value'} = $self->value;
176 Usage : $obj->tagname($newval)
177 Function: Get/set the tagname for this annotation value.
179 Setting this is optional. If set, it obviates the need to provide
180 a tag to AnnotationCollection when adding this object.
182 Returns : value of tagname (a scalar)
183 Args : new value (a scalar, optional)
189 my ($self,$value) = @_;
190 if( defined $value) {
191 $self->{'tagname'} = $value;
193 return $self->{'tagname'};
197 =head1 Specific accessors for StructuredValue
204 Usage : $obj->value($newval)
205 Function: Get/set the value for this annotation.
207 Set mode is here only to retain compatibility with
208 SimpleValue. It is equivalent to calling
209 add_value([0], $newval).
211 In get mode, this implementation allows to pass additional
212 parameters that control how the structured annotation
213 components will be joined together to form a
214 string. Recognized are presently
215 -joins a reference to an array of join strings, the
216 elements at index i applying to joining
217 annotations at dimension i. The last element
218 will be re-used for dimensions higher than i.
220 -brackets a reference to an array of two strings
221 denoting the opening and closing brackets for
222 the elements of one dimension, if there is
223 more than one element in the dimension.
224 Defaults to ['(',')'].
226 Returns : value of value
227 Args : newvalue (optional)
233 my ($self,$value,@args) = @_;
236 return $self->add_value([0], $value) if defined($value) && (@args == 0);
238 # determine joins and brackets
239 unshift(@args, $value);
240 my ($joins, $brackets) =
241 $self->_rearrange([qw(JOINS BRACKETS)], @args);
242 $joins = ['; '] unless $joins;
243 $brackets = ['(', ')'] unless $brackets;
244 my $txt = &_to_text
($self->{'values'}, $joins, $brackets);
245 # if there's only brackets at the start and end, remove them
246 if((@
{$self->{'values'}} == 1) &&
247 (length($brackets->[0]) == 1) && (length($brackets->[1]) == 1)) {
248 my $re = '\\'.$brackets->[0].
249 '([^\\'.$brackets->[1].']*)\\'.$brackets->[1];
256 my ($arr, $joins, $brackets, $rec_n) = @_;
258 $rec_n = 0 unless defined($rec_n);
259 my $i = $rec_n >= @
$joins ? @
$joins-1 : $rec_n;
260 my $txt = join($joins->[$i],
263 (ref($_) eq "ARRAY" ?
264 &_to_text
($_, $joins, $brackets, $rec_n+1) :
268 if($rec_n && (@
$arr > 1)) {
269 $txt = $brackets->[0] . $txt . $brackets->[1];
278 Function: Get the top-level array of values. Each of the elements will
279 recursively be a reference to an array or a scalar, depending
280 on the depth of this structured value annotation.
291 return @
{$self->{'values'}};
294 =head2 get_all_values
296 Title : get_all_values
298 Function: Flattens all values in this structured annotation and
299 returns them as an array.
301 Returns : the (flat) array of values
309 # we code lazy here and just take advantage of value()
310 my $txt = $self->value(-joins
=> ['@!@'], -brackets
=> ['','']);
311 return split(/\@!\@/, $txt);
318 Function: Adds the given value to the structured annotation at the
321 The index is multi-dimensional, with the first dimension
322 applying to the first level, and so forth. If a particular
323 dimension or a particular index does not exist yet, it will
324 be created. If it does exist and adding the value would
325 mean replacing a scalar with an array reference, we throw
326 an exception to prevent unintended damage. An index of -1
327 at any dimension means append.
329 If an array of values is to be added, it will create an
330 additional dimension at the index specified, unless the
331 last index value is -1, in which case they will all be
332 appended to the last dimension.
336 Args : the index at which to add (a reference to an array)
343 my ($self,$index,@values) = @_;
345 my $tree = $self->{'values'};
346 my $lastidx = pop(@
$index);
347 foreach my $i (@
$index) {
350 push(@
$tree, $subtree);
352 } elsif((! $tree->[$i]) || (ref($tree->[$i]) eq "ARRAY")) {
353 $tree->[$i] = [] unless ref($tree->[$i]) eq "ARRAY";
356 $self->throw("element $i is a scalar but not in last dimension");
360 push(@
$tree, @values);
361 } elsif(@values < 2) {
362 $tree->[$lastidx] = shift(@values);
364 $tree->[$lastidx] = [@values];