| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Bio::Phylo; | 
| 2 | 57 |  |  | 57 |  | 426604 | use strict; | 
|  | 57 |  |  |  |  | 144 |  | 
|  | 57 |  |  |  |  | 1503 |  | 
| 3 | 57 |  |  | 57 |  | 14731 | use Bio::PhyloRole; | 
|  | 57 |  |  |  |  | 198 |  | 
|  | 57 |  |  |  |  | 1839 |  | 
| 4 | 57 |  |  | 57 |  | 444 | use base 'Bio::PhyloRole'; | 
|  | 57 |  |  |  |  | 113 |  | 
|  | 57 |  |  |  |  | 6099 |  | 
| 5 |  |  |  |  |  |  |  | 
| 6 |  |  |  |  |  |  | # don't use Scalar::Util::looks_like_number directly, use wrapped version | 
| 7 | 57 |  |  | 57 |  | 362 | use Scalar::Util qw'weaken blessed'; | 
|  | 57 |  |  |  |  | 106 |  | 
|  | 57 |  |  |  |  | 2817 |  | 
| 8 | 57 |  |  | 57 |  | 313 | use Bio::Phylo::Util::CONSTANT '/looks_like/'; | 
|  | 57 |  |  |  |  | 118 |  | 
|  | 57 |  |  |  |  | 6867 |  | 
| 9 | 57 |  |  | 57 |  | 384 | use Bio::Phylo::Util::IDPool;             # creates unique object IDs | 
|  | 57 |  |  |  |  | 99 |  | 
|  | 57 |  |  |  |  | 1200 |  | 
| 10 | 57 |  |  | 57 |  | 293 | use Bio::Phylo::Util::Exceptions 'throw'; # defines exception classes and throws | 
|  | 57 |  |  |  |  | 99 |  | 
|  | 57 |  |  |  |  | 2153 |  | 
| 11 | 57 |  |  | 57 |  | 315 | use Bio::Phylo::Util::Logger;             # for logging, like log4perl/log4j | 
|  | 57 |  |  |  |  | 120 |  | 
|  | 57 |  |  |  |  | 1745 |  | 
| 12 | 57 |  |  | 57 |  | 15669 | use Bio::Phylo::Util::MOP;                # for traversing inheritance trees | 
|  | 57 |  |  |  |  | 180 |  | 
|  | 57 |  |  |  |  | 337 |  | 
| 13 | 57 |  |  | 57 |  | 300 | use Bio::Phylo::Identifiable;             # for storing unique IDs inside an instance | 
|  | 57 |  |  |  |  | 142 |  | 
|  | 57 |  |  |  |  | 2633 |  | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | our ( $logger, $COMPAT ) = Bio::Phylo::Util::Logger->new; | 
| 16 | 57 |  |  | 57 |  | 15931 | use version 0.77; our $VERSION = qv("v0.58_2"); # alpha, change to v2.0.0 when all's good | 
|  | 57 |  |  |  |  | 82008 |  | 
|  | 57 |  |  |  |  | 502 |  | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | # mediates one-to-many relationships between taxon and nodes, | 
| 19 |  |  |  |  |  |  | # taxon and sequences, taxa and forests, taxa and matrices. | 
| 20 |  |  |  |  |  |  | # Read up on the Mediator design pattern to learn how this works. | 
| 21 |  |  |  |  |  |  | require Bio::Phylo::Mediators::TaxaMediator; | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  |  | 
| 24 |  |  |  |  |  |  | { | 
| 25 |  |  |  |  |  |  | my $taxamediator = 'Bio::Phylo::Mediators::TaxaMediator'; | 
| 26 |  |  |  |  |  |  | my $mop = 'Bio::Phylo::Util::MOP'; | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  | sub import { | 
| 29 | 556 |  |  | 556 |  | 1941 | my $class = shift; | 
| 30 | 556 | 50 |  |  |  | 1748 | if (@_) { | 
| 31 | 0 |  |  |  |  | 0 | my %opt = looks_like_hash @_; | 
| 32 | 0 |  |  |  |  | 0 | while ( my ( $key, $value ) = each %opt ) { | 
| 33 | 0 | 0 |  |  |  | 0 | if ( $key =~ qr/^VERBOSE$/i ) { | 
|  |  | 0 |  |  |  |  |  | 
| 34 | 0 |  |  |  |  | 0 | $logger->VERBOSE( '-level' => $value, '-class' => $class ); | 
| 35 |  |  |  |  |  |  | } | 
| 36 |  |  |  |  |  |  | elsif ( $key =~ qr/^COMPAT$/i ) { | 
| 37 | 0 |  |  |  |  | 0 | $COMPAT = ucfirst( lc($value) ); | 
| 38 |  |  |  |  |  |  | } | 
| 39 |  |  |  |  |  |  | else { | 
| 40 | 0 |  |  |  |  | 0 | throw 'BadArgs' => "'$key' is not a valid argument for import"; | 
| 41 |  |  |  |  |  |  | } | 
| 42 |  |  |  |  |  |  | } | 
| 43 |  |  |  |  |  |  | } | 
| 44 | 556 |  |  |  |  | 30477 | return 1; | 
| 45 |  |  |  |  |  |  | } | 
| 46 |  |  |  |  |  |  |  | 
| 47 |  |  |  |  |  |  | # the following hashes are used to hold state of inside-out objects. For | 
| 48 |  |  |  |  |  |  | # example, $obj->set_name("name") is implemented as $name{ $obj->get_id } | 
| 49 |  |  |  |  |  |  | # = $name. To avoid memory leaks (and subtle bugs, should a new object by | 
| 50 |  |  |  |  |  |  | # the same id appear (though that shouldn't happen)), the hash slots | 
| 51 |  |  |  |  |  |  | # occupied by $obj->get_id need to be reclaimed in the destructor. This | 
| 52 |  |  |  |  |  |  | # is done by recursively calling the $obj->_cleanup methods in all of $obj's | 
| 53 |  |  |  |  |  |  | # superclasses. To make that method easier to write, we create an  array | 
| 54 |  |  |  |  |  |  | # with the local inside-out hashes here, so that we can just iterate over | 
| 55 |  |  |  |  |  |  | # them anonymously during destruction cleanup. Other classes do something | 
| 56 |  |  |  |  |  |  | # like this as well. | 
| 57 |  |  |  |  |  |  | my @fields = \( | 
| 58 |  |  |  |  |  |  | my ( | 
| 59 |  |  |  |  |  |  | %guid, | 
| 60 |  |  |  |  |  |  | %desc, | 
| 61 |  |  |  |  |  |  | %score, | 
| 62 |  |  |  |  |  |  | %generic, | 
| 63 |  |  |  |  |  |  | %cache, | 
| 64 |  |  |  |  |  |  | %container,    # XXX weak reference | 
| 65 |  |  |  |  |  |  | %objects       # XXX weak reference | 
| 66 |  |  |  |  |  |  | ) | 
| 67 |  |  |  |  |  |  | ); | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  | =head1 NAME | 
| 70 |  |  |  |  |  |  |  | 
| 71 |  |  |  |  |  |  | Bio::Phylo - Phylogenetic analysis using perl | 
| 72 |  |  |  |  |  |  |  | 
| 73 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 74 |  |  |  |  |  |  |  | 
| 75 |  |  |  |  |  |  | # Actually, you would almost never use this module directly. This is | 
| 76 |  |  |  |  |  |  | # the base class for other modules. | 
| 77 |  |  |  |  |  |  | use Bio::Phylo; | 
| 78 |  |  |  |  |  |  |  | 
| 79 |  |  |  |  |  |  | # sets global verbosity to 'error' | 
| 80 |  |  |  |  |  |  | Bio::Phylo->VERBOSE( -level => Bio::Phylo::Util::Logger::ERROR ); | 
| 81 |  |  |  |  |  |  |  | 
| 82 |  |  |  |  |  |  | # sets verbosity for forest ojects to 'debug' | 
| 83 |  |  |  |  |  |  | Bio::Phylo->VERBOSE( | 
| 84 |  |  |  |  |  |  | -level => Bio::Phylo::Util::Logger::DEBUG, | 
| 85 |  |  |  |  |  |  | -class => 'Bio::Phylo::Forest' | 
| 86 |  |  |  |  |  |  | ); | 
| 87 |  |  |  |  |  |  |  | 
| 88 |  |  |  |  |  |  | # prints version, including SVN revision number | 
| 89 |  |  |  |  |  |  | print Bio::Phylo->VERSION; | 
| 90 |  |  |  |  |  |  |  | 
| 91 |  |  |  |  |  |  | # prints suggested citation | 
| 92 |  |  |  |  |  |  | print Bio::Phylo->CITATION; | 
| 93 |  |  |  |  |  |  |  | 
| 94 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 95 |  |  |  |  |  |  |  | 
| 96 |  |  |  |  |  |  | This is the base class for the Bio::Phylo package for phylogenetic analysis using | 
| 97 |  |  |  |  |  |  | object-oriented perl5. In this file, methods are defined that are performed by other | 
| 98 |  |  |  |  |  |  | objects in the Bio::Phylo release that inherit from this base class (which you normally | 
| 99 |  |  |  |  |  |  | wouldn't use directly). | 
| 100 |  |  |  |  |  |  |  | 
| 101 |  |  |  |  |  |  | For general information on how to use Bio::Phylo, consult the manual | 
| 102 |  |  |  |  |  |  | (L). | 
| 103 |  |  |  |  |  |  |  | 
| 104 |  |  |  |  |  |  | If you come here because you are trying to debug a problem you run into in | 
| 105 |  |  |  |  |  |  | using Bio::Phylo, you may be interested in the "exceptions" system as discussed | 
| 106 |  |  |  |  |  |  | in L. In addition, you may find the logging system | 
| 107 |  |  |  |  |  |  | in L of use to localize problems. | 
| 108 |  |  |  |  |  |  |  | 
| 109 |  |  |  |  |  |  | =head1 METHODS | 
| 110 |  |  |  |  |  |  |  | 
| 111 |  |  |  |  |  |  | =head2 CONSTRUCTOR | 
| 112 |  |  |  |  |  |  |  | 
| 113 |  |  |  |  |  |  | =over | 
| 114 |  |  |  |  |  |  |  | 
| 115 |  |  |  |  |  |  | =item new() | 
| 116 |  |  |  |  |  |  |  | 
| 117 |  |  |  |  |  |  | The Bio::Phylo root constructor is rarely used directly. Rather, many other | 
| 118 |  |  |  |  |  |  | objects in Bio::Phylo internally go up the inheritance tree to this constructor. | 
| 119 |  |  |  |  |  |  | The arguments shown here can therefore also be passed to any of the child | 
| 120 |  |  |  |  |  |  | classes' constructors, which will pass them on up the inheritance tree. Generally, | 
| 121 |  |  |  |  |  |  | constructors in Bio::Phylo subclasses can process as arguments all methods that | 
| 122 |  |  |  |  |  |  | have set_* in their names. The arguments are named for the methods, but "set_" | 
| 123 |  |  |  |  |  |  | has been replaced with a dash "-", e.g. the method "set_name" becomes the | 
| 124 |  |  |  |  |  |  | argument "-name" in the constructor. | 
| 125 |  |  |  |  |  |  |  | 
| 126 |  |  |  |  |  |  | Type    : Constructor | 
| 127 |  |  |  |  |  |  | Title   : new | 
| 128 |  |  |  |  |  |  | Usage   : my $phylo = Bio::Phylo->new; | 
| 129 |  |  |  |  |  |  | Function: Instantiates Bio::Phylo object | 
| 130 |  |  |  |  |  |  | Returns : a Bio::Phylo object | 
| 131 |  |  |  |  |  |  | Args    : Optional, any number of setters. For example, | 
| 132 |  |  |  |  |  |  | Bio::Phylo->new( -name => $name ) | 
| 133 |  |  |  |  |  |  | will call set_name( $name ) internally | 
| 134 |  |  |  |  |  |  |  | 
| 135 |  |  |  |  |  |  | =cut | 
| 136 |  |  |  |  |  |  |  | 
| 137 |  |  |  |  |  |  | sub new : Constructor { | 
| 138 |  |  |  |  |  |  |  | 
| 139 |  |  |  |  |  |  | # $class could be a child class, called from $class->SUPER::new(@_) | 
| 140 |  |  |  |  |  |  | # or an object, e.g. $node->new(%args) in which case we create a new | 
| 141 |  |  |  |  |  |  | # object that's bless into the same class as the invocant. No, that's | 
| 142 |  |  |  |  |  |  | # not the same thing as a clone. | 
| 143 | 12044 |  |  | 12044 | 1 | 19842 | my $class = shift; | 
| 144 | 12044 | 50 |  |  |  | 25456 | if ( my $reference = ref $class ) { | 
| 145 | 0 |  |  |  |  | 0 | $class = $reference; | 
| 146 |  |  |  |  |  |  | } | 
| 147 |  |  |  |  |  |  |  | 
| 148 |  |  |  |  |  |  | # happens only and exactly once because this | 
| 149 |  |  |  |  |  |  | # root class is visited from every constructor | 
| 150 | 12044 |  |  |  |  | 29520 | my $self = $class->SUPER::new(); | 
| 151 |  |  |  |  |  |  |  | 
| 152 |  |  |  |  |  |  | # register for get_obj_by_id | 
| 153 | 12044 |  |  |  |  | 24951 | my $id = $self->get_id; | 
| 154 | 12044 |  |  |  |  | 30343 | $objects{$id} = $self; | 
| 155 | 12044 |  |  |  |  | 35169 | weaken( $objects{$id} ); | 
| 156 |  |  |  |  |  |  |  | 
| 157 |  |  |  |  |  |  | # notify user | 
| 158 | 12044 |  |  |  |  | 45632 | $logger->info("constructor called for '$class' - $id"); | 
| 159 |  |  |  |  |  |  |  | 
| 160 |  |  |  |  |  |  | # processing arguments | 
| 161 | 12044 | 100 | 66 |  |  | 32340 | if ( @_ and @_ = looks_like_hash @_ ) { | 
| 162 | 2934 |  |  |  |  | 7842 | $logger->info("processing arguments"); | 
| 163 |  |  |  |  |  |  |  | 
| 164 |  |  |  |  |  |  | # process all arguments | 
| 165 | 2934 |  |  |  |  | 6080 | ARG: while (@_) { | 
| 166 | 5788 |  |  |  |  | 8952 | my $key   = shift @_; | 
| 167 | 5788 |  |  |  |  | 7817 | my $value = shift @_; | 
| 168 |  |  |  |  |  |  |  | 
| 169 |  |  |  |  |  |  | # this is a bioperl arg, meant to set | 
| 170 |  |  |  |  |  |  | # verbosity at a per class basis. In | 
| 171 |  |  |  |  |  |  | # bioperl, the $verbose argument is | 
| 172 |  |  |  |  |  |  | # subsequently carried around in that | 
| 173 |  |  |  |  |  |  | # class, here we delegate that to the | 
| 174 |  |  |  |  |  |  | # logger, which has roughly the same | 
| 175 |  |  |  |  |  |  | # effect. | 
| 176 | 5788 | 50 |  |  |  | 10117 | if ( $key eq '-verbose' ) { | 
| 177 | 0 |  |  |  |  | 0 | $logger->VERBOSE( | 
| 178 |  |  |  |  |  |  | '-level' => $value, | 
| 179 |  |  |  |  |  |  | '-class' => $class, | 
| 180 |  |  |  |  |  |  | ); | 
| 181 | 0 |  |  |  |  | 0 | next ARG; | 
| 182 |  |  |  |  |  |  | } | 
| 183 |  |  |  |  |  |  |  | 
| 184 |  |  |  |  |  |  | # notify user | 
| 185 | 5788 |  |  |  |  | 23609 | $logger->debug("processing constructor arg '${key}' => '${value}'"); | 
| 186 |  |  |  |  |  |  |  | 
| 187 |  |  |  |  |  |  | # don't access data structures directly, call mutators | 
| 188 |  |  |  |  |  |  | # in child classes or __PACKAGE__ | 
| 189 | 5788 |  |  |  |  | 8902 | my $mutator = $key; | 
| 190 | 5788 |  |  |  |  | 20984 | $mutator =~ s/^-/set_/; | 
| 191 |  |  |  |  |  |  |  | 
| 192 |  |  |  |  |  |  | # backward compat fixes: | 
| 193 | 5788 |  |  |  |  | 9850 | $mutator =~ s/^set_pos$/set_position/; | 
| 194 | 5788 |  |  |  |  | 7513 | $mutator =~ s/^set_matrix$/set_raw/; | 
| 195 | 5788 |  |  |  |  | 7454 | eval { $self->$mutator($value); }; | 
|  | 5788 |  |  |  |  | 17644 |  | 
| 196 | 5788 | 50 |  |  |  | 16817 | if ($@) { | 
| 197 | 0 | 0 | 0 |  |  | 0 | if ( blessed $@ and $@->can('rethrow') ) { | 
|  |  | 0 | 0 |  |  |  |  | 
| 198 | 0 |  |  |  |  | 0 | $@->rethrow; | 
| 199 |  |  |  |  |  |  | } | 
| 200 |  |  |  |  |  |  | elsif ( not ref($@) and $@ =~ /^Can't locate object method / ) { | 
| 201 | 0 |  |  |  |  | 0 | throw 'BadArgs' => "The named argument '${key}' cannot be passed to the constructor of ${class}"; | 
| 202 |  |  |  |  |  |  | } | 
| 203 |  |  |  |  |  |  | else { | 
| 204 | 0 |  |  |  |  | 0 | throw 'Generic' => $@; | 
| 205 |  |  |  |  |  |  | } | 
| 206 |  |  |  |  |  |  | } | 
| 207 |  |  |  |  |  |  | } | 
| 208 |  |  |  |  |  |  | } | 
| 209 | 12044 |  |  |  |  | 33042 | $logger->info("done processing constructor arguments"); | 
| 210 |  |  |  |  |  |  |  | 
| 211 |  |  |  |  |  |  | # register with mediator | 
| 212 |  |  |  |  |  |  | # TODO this is irrelevant for some child classes, | 
| 213 |  |  |  |  |  |  | # so should be re-factored into somewhere nearer the | 
| 214 |  |  |  |  |  |  | # tips of the inheritance tree. The hack where we | 
| 215 |  |  |  |  |  |  | # skip over direct instances of Writable is so that | 
| 216 |  |  |  |  |  |  | # we don't register things like  and  tags | 
| 217 | 12044 | 100 | 66 |  |  | 74429 | if ( ref $self ne 'Bio::Phylo::NeXML::Writable' && ! $self->isa('Bio::Phylo::Matrices::Datatype') ) { | 
| 218 | 11208 |  |  |  |  | 42059 | $logger->info("going to register $self with $taxamediator"); | 
| 219 | 11208 |  |  |  |  | 32703 | $taxamediator->register($self); | 
| 220 |  |  |  |  |  |  | } | 
| 221 | 12044 |  |  |  |  | 30624 | $logger->info("done building object"); | 
| 222 | 12044 |  |  |  |  | 29237 | return $self; | 
| 223 | 57 |  |  | 57 |  | 37653 | } | 
|  | 57 |  |  |  |  | 137 |  | 
|  | 57 |  |  |  |  | 321 |  | 
| 224 |  |  |  |  |  |  |  | 
| 225 |  |  |  |  |  |  | =back | 
| 226 |  |  |  |  |  |  |  | 
| 227 |  |  |  |  |  |  | =head2 MUTATORS | 
| 228 |  |  |  |  |  |  |  | 
| 229 |  |  |  |  |  |  | =over | 
| 230 |  |  |  |  |  |  |  | 
| 231 |  |  |  |  |  |  | =item set_guid() | 
| 232 |  |  |  |  |  |  |  | 
| 233 |  |  |  |  |  |  | Sets invocant GUID. | 
| 234 |  |  |  |  |  |  |  | 
| 235 |  |  |  |  |  |  | Type    : Mutator | 
| 236 |  |  |  |  |  |  | Title   : set_guid | 
| 237 |  |  |  |  |  |  | Usage   : $obj->set_guid($guid); | 
| 238 |  |  |  |  |  |  | Function: Assigns an object's GUID. | 
| 239 |  |  |  |  |  |  | Returns : Modified object. | 
| 240 |  |  |  |  |  |  | Args    : A scalar | 
| 241 |  |  |  |  |  |  | Notes   : This field can be used for storing an identifier that is | 
| 242 |  |  |  |  |  |  | unambiguous within a given content. For example, an LSID, | 
| 243 |  |  |  |  |  |  | a genbank accession number, etc. | 
| 244 |  |  |  |  |  |  |  | 
| 245 |  |  |  |  |  |  | =cut | 
| 246 |  |  |  |  |  |  |  | 
| 247 |  |  |  |  |  |  | sub set_guid : Clonable { | 
| 248 | 109 |  |  | 109 | 1 | 167 | my ( $self, $guid ) = @_; | 
| 249 | 109 | 50 |  |  |  | 174 | if ( defined $guid ) { | 
| 250 | 0 |  |  |  |  | 0 | $guid{ $self->get_id } = $guid; | 
| 251 |  |  |  |  |  |  | } | 
| 252 |  |  |  |  |  |  | else { | 
| 253 | 109 |  |  |  |  | 183 | delete $guid{ $self->get_id }; | 
| 254 |  |  |  |  |  |  | } | 
| 255 | 109 |  |  |  |  | 182 | return $self; | 
| 256 | 57 |  |  | 57 |  | 16145 | } | 
|  | 57 |  |  |  |  | 143 |  | 
|  | 57 |  |  |  |  | 256 |  | 
| 257 |  |  |  |  |  |  |  | 
| 258 |  |  |  |  |  |  |  | 
| 259 |  |  |  |  |  |  | =item set_desc() | 
| 260 |  |  |  |  |  |  |  | 
| 261 |  |  |  |  |  |  | Sets invocant description. | 
| 262 |  |  |  |  |  |  |  | 
| 263 |  |  |  |  |  |  | Type    : Mutator | 
| 264 |  |  |  |  |  |  | Title   : set_desc | 
| 265 |  |  |  |  |  |  | Usage   : $obj->set_desc($desc); | 
| 266 |  |  |  |  |  |  | Function: Assigns an object's description. | 
| 267 |  |  |  |  |  |  | Returns : Modified object. | 
| 268 |  |  |  |  |  |  | Args    : Argument must be a string. | 
| 269 |  |  |  |  |  |  |  | 
| 270 |  |  |  |  |  |  | =cut | 
| 271 |  |  |  |  |  |  |  | 
| 272 |  |  |  |  |  |  | sub set_desc : Clonable { | 
| 273 | 111 |  |  | 111 | 1 | 166 | my ( $self, $desc ) = @_; | 
| 274 | 111 | 100 |  |  |  | 166 | if ( defined $desc ) { | 
| 275 | 2 |  |  |  |  | 7 | $desc{ $self->get_id } = $desc; | 
| 276 |  |  |  |  |  |  | } | 
| 277 |  |  |  |  |  |  | else { | 
| 278 | 109 |  |  |  |  | 174 | delete $desc{ $self->get_id }; | 
| 279 |  |  |  |  |  |  | } | 
| 280 | 111 |  |  |  |  | 211 | return $self; | 
| 281 | 57 |  |  | 57 |  | 12732 | } | 
|  | 57 |  |  |  |  | 456 |  | 
|  | 57 |  |  |  |  | 193 |  | 
| 282 |  |  |  |  |  |  |  | 
| 283 |  |  |  |  |  |  | =item set_score() | 
| 284 |  |  |  |  |  |  |  | 
| 285 |  |  |  |  |  |  | Sets invocant score. | 
| 286 |  |  |  |  |  |  |  | 
| 287 |  |  |  |  |  |  | Type    : Mutator | 
| 288 |  |  |  |  |  |  | Title   : set_score | 
| 289 |  |  |  |  |  |  | Usage   : $obj->set_score($score); | 
| 290 |  |  |  |  |  |  | Function: Assigns an object's numerical score. | 
| 291 |  |  |  |  |  |  | Returns : Modified object. | 
| 292 |  |  |  |  |  |  | Args    : Argument must be any of | 
| 293 |  |  |  |  |  |  | perl's number formats, or undefined | 
| 294 |  |  |  |  |  |  | to reset score. | 
| 295 |  |  |  |  |  |  |  | 
| 296 |  |  |  |  |  |  | =cut | 
| 297 |  |  |  |  |  |  |  | 
| 298 |  |  |  |  |  |  | sub set_score : Clonable { | 
| 299 | 109 |  |  | 109 | 1 | 191 | my ( $self, $score ) = @_; | 
| 300 |  |  |  |  |  |  |  | 
| 301 |  |  |  |  |  |  | # $score must be a number (or undefined) | 
| 302 | 109 | 50 |  |  |  | 170 | if ( defined $score ) { | 
| 303 | 0 | 0 |  |  |  | 0 | if ( !looks_like_number($score) ) { | 
| 304 | 0 |  |  |  |  | 0 | throw 'BadNumber' => "score \"$score\" is a bad number"; | 
| 305 |  |  |  |  |  |  | } | 
| 306 |  |  |  |  |  |  |  | 
| 307 |  |  |  |  |  |  | # notify user | 
| 308 | 0 |  |  |  |  | 0 | $logger->info("setting score '$score'"); | 
| 309 | 0 |  |  |  |  | 0 | $score{ $self->get_id } = $score; | 
| 310 |  |  |  |  |  |  | } | 
| 311 |  |  |  |  |  |  | else { | 
| 312 | 109 |  |  |  |  | 273 | $logger->info("unsetting score"); | 
| 313 | 109 |  |  |  |  | 197 | delete $score{ $self->get_id }; | 
| 314 |  |  |  |  |  |  | } | 
| 315 |  |  |  |  |  |  |  | 
| 316 | 109 |  |  |  |  | 209 | return $self; | 
| 317 | 57 |  |  | 57 |  | 15377 | } | 
|  | 57 |  |  |  |  | 326 |  | 
|  | 57 |  |  |  |  | 222 |  | 
| 318 |  |  |  |  |  |  |  | 
| 319 |  |  |  |  |  |  | =item set_generic() | 
| 320 |  |  |  |  |  |  |  | 
| 321 |  |  |  |  |  |  | Sets generic key/value pair(s). | 
| 322 |  |  |  |  |  |  |  | 
| 323 |  |  |  |  |  |  | Type    : Mutator | 
| 324 |  |  |  |  |  |  | Title   : set_generic | 
| 325 |  |  |  |  |  |  | Usage   : $obj->set_generic( %generic ); | 
| 326 |  |  |  |  |  |  | Function: Assigns generic key/value pairs to the invocant. | 
| 327 |  |  |  |  |  |  | Returns : Modified object. | 
| 328 |  |  |  |  |  |  | Args    : Valid arguments constitute: | 
| 329 |  |  |  |  |  |  |  | 
| 330 |  |  |  |  |  |  | * key/value pairs, for example: | 
| 331 |  |  |  |  |  |  | $obj->set_generic( '-lnl' => 0.87565 ); | 
| 332 |  |  |  |  |  |  |  | 
| 333 |  |  |  |  |  |  | * or a hash ref, for example: | 
| 334 |  |  |  |  |  |  | $obj->set_generic( { '-lnl' => 0.87565 } ); | 
| 335 |  |  |  |  |  |  |  | 
| 336 |  |  |  |  |  |  | * or nothing, to reset the stored hash, e.g. | 
| 337 |  |  |  |  |  |  | $obj->set_generic( ); | 
| 338 |  |  |  |  |  |  |  | 
| 339 |  |  |  |  |  |  | =cut | 
| 340 |  |  |  |  |  |  |  | 
| 341 |  |  |  |  |  |  | sub set_generic : Clonable { | 
| 342 | 2596 |  |  | 2596 | 1 | 3447 | my $self = shift; | 
| 343 |  |  |  |  |  |  |  | 
| 344 |  |  |  |  |  |  | # retrieve id just once, don't call $self->get_id in loops, inefficient | 
| 345 | 2596 |  |  |  |  | 4950 | my $id = $self->get_id; | 
| 346 |  |  |  |  |  |  |  | 
| 347 |  |  |  |  |  |  | # this initializes the hash if it didn't exist yet, or resets it if no args | 
| 348 | 2596 | 100 | 66 |  |  | 8749 | if ( !defined $generic{$id} || !@_ ) { | 
| 349 | 1979 |  |  |  |  | 5308 | $generic{$id} = {}; | 
| 350 |  |  |  |  |  |  | } | 
| 351 |  |  |  |  |  |  |  | 
| 352 |  |  |  |  |  |  | # have args | 
| 353 | 2596 | 50 |  |  |  | 5226 | if (@_) { | 
| 354 | 2596 |  |  |  |  | 3430 | my %args; | 
| 355 |  |  |  |  |  |  |  | 
| 356 |  |  |  |  |  |  | # have a single arg, a hash ref | 
| 357 | 2596 | 100 | 66 |  |  | 6507 | if ( scalar @_ == 1 && looks_like_instance( $_[0], 'HASH' ) ) { | 
| 358 | 128 |  |  |  |  | 166 | %args = %{ $_[0] }; | 
|  | 128 |  |  |  |  | 273 |  | 
| 359 |  |  |  |  |  |  | } | 
| 360 |  |  |  |  |  |  |  | 
| 361 |  |  |  |  |  |  | # multiple args, hopefully even size key/value pairs | 
| 362 |  |  |  |  |  |  | else { | 
| 363 | 2468 |  |  |  |  | 6883 | %args = looks_like_hash @_; | 
| 364 |  |  |  |  |  |  | } | 
| 365 |  |  |  |  |  |  |  | 
| 366 |  |  |  |  |  |  | # notify user | 
| 367 | 2596 |  |  |  |  | 9430 | $logger->info("setting generic key/value pairs %{args}"); | 
| 368 |  |  |  |  |  |  |  | 
| 369 |  |  |  |  |  |  | # fill up the hash | 
| 370 | 2596 |  |  |  |  | 5848 | for my $key ( keys %args ) { | 
| 371 | 2487 |  |  |  |  | 7479 | $generic{$id}->{$key} = $args{$key}; | 
| 372 |  |  |  |  |  |  | } | 
| 373 |  |  |  |  |  |  | } | 
| 374 | 2596 |  |  |  |  | 5455 | return $self; | 
| 375 | 57 |  |  | 57 |  | 17871 | } | 
|  | 57 |  |  |  |  | 115 |  | 
|  | 57 |  |  |  |  | 197 |  | 
| 376 |  |  |  |  |  |  |  | 
| 377 |  |  |  |  |  |  | =back | 
| 378 |  |  |  |  |  |  |  | 
| 379 |  |  |  |  |  |  | =head2 ACCESSORS | 
| 380 |  |  |  |  |  |  |  | 
| 381 |  |  |  |  |  |  | =over | 
| 382 |  |  |  |  |  |  |  | 
| 383 |  |  |  |  |  |  | =item get_guid() | 
| 384 |  |  |  |  |  |  |  | 
| 385 |  |  |  |  |  |  | Gets invocant GUID. | 
| 386 |  |  |  |  |  |  |  | 
| 387 |  |  |  |  |  |  | Type    : Accessor | 
| 388 |  |  |  |  |  |  | Title   : get_guid | 
| 389 |  |  |  |  |  |  | Usage   : my $guid = $obj->get_guid; | 
| 390 |  |  |  |  |  |  | Function: Assigns an object's GUID. | 
| 391 |  |  |  |  |  |  | Returns : Scalar. | 
| 392 |  |  |  |  |  |  | Args    : None | 
| 393 |  |  |  |  |  |  | Notes   : This field can be used for storing an identifier that is | 
| 394 |  |  |  |  |  |  | unambiguous within a given content. For example, an LSID, | 
| 395 |  |  |  |  |  |  | a genbank accession number, etc. | 
| 396 |  |  |  |  |  |  |  | 
| 397 |  |  |  |  |  |  | =cut | 
| 398 |  |  |  |  |  |  |  | 
| 399 | 109 |  |  | 109 | 1 | 241 | sub get_guid { $guid{ shift->get_id } } | 
| 400 |  |  |  |  |  |  |  | 
| 401 |  |  |  |  |  |  | =item get_desc() | 
| 402 |  |  |  |  |  |  |  | 
| 403 |  |  |  |  |  |  | Gets invocant description. | 
| 404 |  |  |  |  |  |  |  | 
| 405 |  |  |  |  |  |  | Type    : Accessor | 
| 406 |  |  |  |  |  |  | Title   : get_desc | 
| 407 |  |  |  |  |  |  | Usage   : my $desc = $obj->get_desc; | 
| 408 |  |  |  |  |  |  | Function: Returns the object's description (if any). | 
| 409 |  |  |  |  |  |  | Returns : A string | 
| 410 |  |  |  |  |  |  | Args    : None | 
| 411 |  |  |  |  |  |  |  | 
| 412 |  |  |  |  |  |  | =cut | 
| 413 |  |  |  |  |  |  |  | 
| 414 | 111 |  |  | 111 | 1 | 238 | sub get_desc { $desc{ shift->get_id } } | 
| 415 |  |  |  |  |  |  |  | 
| 416 |  |  |  |  |  |  | =item get_score() | 
| 417 |  |  |  |  |  |  |  | 
| 418 |  |  |  |  |  |  | Gets invocant's score. | 
| 419 |  |  |  |  |  |  |  | 
| 420 |  |  |  |  |  |  | Type    : Accessor | 
| 421 |  |  |  |  |  |  | Title   : get_score | 
| 422 |  |  |  |  |  |  | Usage   : my $score = $obj->get_score; | 
| 423 |  |  |  |  |  |  | Function: Returns the object's numerical score (if any). | 
| 424 |  |  |  |  |  |  | Returns : A number | 
| 425 |  |  |  |  |  |  | Args    : None | 
| 426 |  |  |  |  |  |  |  | 
| 427 |  |  |  |  |  |  | =cut | 
| 428 |  |  |  |  |  |  |  | 
| 429 | 109 |  |  | 109 | 1 | 213 | sub get_score { $score{ shift->get_id } } | 
| 430 |  |  |  |  |  |  |  | 
| 431 |  |  |  |  |  |  | =item get_generic() | 
| 432 |  |  |  |  |  |  |  | 
| 433 |  |  |  |  |  |  | Gets generic hashref or hash value(s). | 
| 434 |  |  |  |  |  |  |  | 
| 435 |  |  |  |  |  |  | Type    : Accessor | 
| 436 |  |  |  |  |  |  | Title   : get_generic | 
| 437 |  |  |  |  |  |  | Usage   : my $value = $obj->get_generic($key); | 
| 438 |  |  |  |  |  |  | or | 
| 439 |  |  |  |  |  |  | my %hash = %{ $obj->get_generic() }; | 
| 440 |  |  |  |  |  |  | Function: Returns the object's generic data. If an | 
| 441 |  |  |  |  |  |  | argument is used, it is considered a key | 
| 442 |  |  |  |  |  |  | for which the associated value is returned. | 
| 443 |  |  |  |  |  |  | Without arguments, a reference to the whole | 
| 444 |  |  |  |  |  |  | hash is returned. | 
| 445 |  |  |  |  |  |  | Returns : A value or an array reference of values | 
| 446 |  |  |  |  |  |  | Args    : A key (string) or an array reference of keys | 
| 447 |  |  |  |  |  |  |  | 
| 448 |  |  |  |  |  |  | =cut | 
| 449 |  |  |  |  |  |  |  | 
| 450 |  |  |  |  |  |  | sub get_generic { | 
| 451 | 3536 |  |  | 3536 | 1 | 5372 | my ( $self, $key ) = @_; | 
| 452 |  |  |  |  |  |  |  | 
| 453 |  |  |  |  |  |  | # retrieve just once | 
| 454 | 3536 |  |  |  |  | 6513 | my $id = $self->get_id; | 
| 455 |  |  |  |  |  |  |  | 
| 456 |  |  |  |  |  |  | # might not even have a generic hash yet, make one on-the-fly | 
| 457 | 3536 | 100 |  |  |  | 7951 | if ( not defined $generic{$id} ) { | 
| 458 | 74 |  |  |  |  | 147 | $generic{$id} = {}; | 
| 459 |  |  |  |  |  |  | } | 
| 460 |  |  |  |  |  |  |  | 
| 461 |  |  |  |  |  |  | # have an argument | 
| 462 | 3536 | 100 |  |  |  | 5652 | if ( defined $key ) { | 
| 463 |  |  |  |  |  |  |  | 
| 464 | 3427 | 50 |  |  |  | 5645 | if ( ref($key) eq 'ARRAY' ) { | 
| 465 | 0 |  |  |  |  | 0 | my @result = @generic{@$key}; | 
| 466 | 0 |  |  |  |  | 0 | return \@result; | 
| 467 |  |  |  |  |  |  | } | 
| 468 |  |  |  |  |  |  | else { | 
| 469 |  |  |  |  |  |  | # notify user | 
| 470 | 3427 |  |  |  |  | 10671 | $logger->debug("getting value for key '$key'"); | 
| 471 | 3427 |  |  |  |  | 11665 | return $generic{$id}->{$key}; | 
| 472 |  |  |  |  |  |  | } | 
| 473 |  |  |  |  |  |  | } | 
| 474 |  |  |  |  |  |  |  | 
| 475 |  |  |  |  |  |  | # no argument, wants whole hash | 
| 476 |  |  |  |  |  |  | else { | 
| 477 |  |  |  |  |  |  |  | 
| 478 |  |  |  |  |  |  | # notify user | 
| 479 | 109 |  |  |  |  | 282 | $logger->debug("retrieving generic hash"); | 
| 480 | 109 |  |  |  |  | 199 | return $generic{$id}; | 
| 481 |  |  |  |  |  |  | } | 
| 482 |  |  |  |  |  |  | } | 
| 483 |  |  |  |  |  |  |  | 
| 484 |  |  |  |  |  |  | =back | 
| 485 |  |  |  |  |  |  |  | 
| 486 |  |  |  |  |  |  | =head2 PACKAGE METHODS | 
| 487 |  |  |  |  |  |  |  | 
| 488 |  |  |  |  |  |  | =over | 
| 489 |  |  |  |  |  |  |  | 
| 490 |  |  |  |  |  |  | =item get_obj_by_id() | 
| 491 |  |  |  |  |  |  |  | 
| 492 |  |  |  |  |  |  | Attempts to fetch an in-memory object by its UID | 
| 493 |  |  |  |  |  |  |  | 
| 494 |  |  |  |  |  |  | Type    : Accessor | 
| 495 |  |  |  |  |  |  | Title   : get_obj_by_id | 
| 496 |  |  |  |  |  |  | Usage   : my $obj = Bio::Phylo->get_obj_by_id($uid); | 
| 497 |  |  |  |  |  |  | Function: Fetches an object from the IDPool cache | 
| 498 |  |  |  |  |  |  | Returns : A Bio::Phylo object | 
| 499 |  |  |  |  |  |  | Args    : A unique id | 
| 500 |  |  |  |  |  |  |  | 
| 501 |  |  |  |  |  |  | =cut | 
| 502 |  |  |  |  |  |  |  | 
| 503 |  |  |  |  |  |  | sub get_obj_by_id { | 
| 504 | 42 |  |  | 42 | 1 | 29225 | my ( $class, $id ) = @_; | 
| 505 | 42 |  |  |  |  | 418 | return $objects{$id}; | 
| 506 |  |  |  |  |  |  | } | 
| 507 |  |  |  |  |  |  |  | 
| 508 |  |  |  |  |  |  | =item get_logger() | 
| 509 |  |  |  |  |  |  |  | 
| 510 |  |  |  |  |  |  | Returns a singleton reference to a Bio::Phylo::Util::Logger object | 
| 511 |  |  |  |  |  |  |  | 
| 512 |  |  |  |  |  |  | Type    : Accessor | 
| 513 |  |  |  |  |  |  | Title   : get_logger | 
| 514 |  |  |  |  |  |  | Usage   : my $logger = Bio::Phylo->get_logger | 
| 515 |  |  |  |  |  |  | Function: Returns logger | 
| 516 |  |  |  |  |  |  | Returns : A Bio::Phylo::Util::Logger object | 
| 517 |  |  |  |  |  |  | Args    : None | 
| 518 |  |  |  |  |  |  |  | 
| 519 |  |  |  |  |  |  | =cut | 
| 520 |  |  |  |  |  |  |  | 
| 521 | 414 |  |  | 414 | 1 | 1428 | sub get_logger { $logger } | 
| 522 |  |  |  |  |  |  |  | 
| 523 |  |  |  |  |  |  | =item VERSION() | 
| 524 |  |  |  |  |  |  |  | 
| 525 |  |  |  |  |  |  | Returns the $VERSION string of this Bio::Phylo release | 
| 526 |  |  |  |  |  |  |  | 
| 527 |  |  |  |  |  |  | Type    : Accessor | 
| 528 |  |  |  |  |  |  | Title   : VERSION | 
| 529 |  |  |  |  |  |  | Usage   : my $version = Bio::Phylo->VERSION | 
| 530 |  |  |  |  |  |  | Function: Returns version string | 
| 531 |  |  |  |  |  |  | Returns : A string | 
| 532 |  |  |  |  |  |  | Args    : None | 
| 533 |  |  |  |  |  |  |  | 
| 534 |  |  |  |  |  |  | =cut | 
| 535 |  |  |  |  |  |  |  | 
| 536 | 9 |  |  | 9 | 1 | 398 | sub VERSION { $VERSION } | 
| 537 |  |  |  |  |  |  |  | 
| 538 |  |  |  |  |  |  | =item clone() | 
| 539 |  |  |  |  |  |  |  | 
| 540 |  |  |  |  |  |  | Clones invocant. | 
| 541 |  |  |  |  |  |  |  | 
| 542 |  |  |  |  |  |  | Type    : Utility method | 
| 543 |  |  |  |  |  |  | Title   : clone | 
| 544 |  |  |  |  |  |  | Usage   : my $clone = $object->clone; | 
| 545 |  |  |  |  |  |  | Function: Creates a copy of the invocant object. | 
| 546 |  |  |  |  |  |  | Returns : A copy of the invocant. | 
| 547 |  |  |  |  |  |  | Args    : None. | 
| 548 |  |  |  |  |  |  | Comments: Cloning is currently experimental, use with caution. | 
| 549 |  |  |  |  |  |  |  | 
| 550 |  |  |  |  |  |  | =cut | 
| 551 |  |  |  |  |  |  |  | 
| 552 |  |  |  |  |  |  | sub clone { | 
| 553 | 109 |  |  | 109 | 1 | 200 | my ( $self, $deep ) = @_; | 
| 554 | 109 | 100 |  |  |  | 211 | $deep = 1 unless defined $deep; | 
| 555 |  |  |  |  |  |  |  | 
| 556 |  |  |  |  |  |  | # compute and instantiate the constructor nearest to the tips of | 
| 557 |  |  |  |  |  |  | # the inheritance tree | 
| 558 | 109 |  |  |  |  | 258 | my $constructors = $mop->get_constructors($self); my $clone = | 
| 559 | 109 |  |  |  |  | 321 | $constructors->[0]->{'code'}->(ref $self); | 
| 560 |  |  |  |  |  |  |  | 
| 561 |  |  |  |  |  |  | # keep track of which methods we've done, including overrides | 
| 562 | 109 |  |  |  |  | 162 | my %seen; | 
| 563 |  |  |  |  |  |  |  | 
| 564 |  |  |  |  |  |  | # do the deep cloning first | 
| 565 | 109 | 100 |  |  |  | 192 | if ( $deep ) { | 
| 566 |  |  |  |  |  |  |  | 
| 567 |  |  |  |  |  |  | # get the deeply clonable methods | 
| 568 | 108 |  |  |  |  | 307 | my $clonables = $mop->get_deep_clonables($self); | 
| 569 | 108 |  |  |  |  | 149 | for my $setter ( @{ $clonables } ) { | 
|  | 108 |  |  |  |  | 176 |  | 
| 570 | 115 |  |  |  |  | 176 | my $setter_name = $setter->{'name'}; | 
| 571 |  |  |  |  |  |  |  | 
| 572 |  |  |  |  |  |  | # only do this for the shallowest method with | 
| 573 |  |  |  |  |  |  | # the same name: the others are overrided | 
| 574 | 115 | 50 |  |  |  | 209 | if ( not $seen{$setter_name} ) { | 
| 575 | 115 |  |  |  |  | 171 | $seen{$setter_name}++; | 
| 576 |  |  |  |  |  |  |  | 
| 577 |  |  |  |  |  |  | # pass the output of the getter to the | 
| 578 |  |  |  |  |  |  | # input of the setter | 
| 579 | 115 |  |  |  |  | 267 | my $output = $self->_get_clonable_output($setter); | 
| 580 | 115 |  |  |  |  | 137 | my $input; | 
| 581 | 115 | 100 | 66 |  |  | 403 | if ( ref $output eq 'ARRAY' ) { | 
|  |  | 100 |  |  |  |  |  | 
| 582 |  |  |  |  |  |  | $input = [ | 
| 583 | 123 | 100 |  |  |  | 335 | map { ref $_ ? $_->clone($deep) : $_ } | 
| 584 | 30 |  |  |  |  | 37 | @{ $output } | 
|  | 30 |  |  |  |  | 63 |  | 
| 585 |  |  |  |  |  |  | ]; | 
| 586 |  |  |  |  |  |  | } | 
| 587 |  |  |  |  |  |  | elsif ( $output and ref $output ) { | 
| 588 | 56 |  |  |  |  | 262 | $input = $output->clone($deep); | 
| 589 |  |  |  |  |  |  | } | 
| 590 | 115 |  |  |  |  | 335 | $setter->{'code'}->($clone,$input); | 
| 591 |  |  |  |  |  |  | } | 
| 592 |  |  |  |  |  |  | } | 
| 593 |  |  |  |  |  |  | } | 
| 594 |  |  |  |  |  |  |  | 
| 595 |  |  |  |  |  |  | # get the clonable methods | 
| 596 | 109 |  |  |  |  | 311 | my $clonables = $mop->get_clonables($self); | 
| 597 | 109 |  |  |  |  | 131 | for my $setter ( @{ $clonables } ) { | 
|  | 109 |  |  |  |  | 165 |  | 
| 598 | 1852 |  |  |  |  | 2501 | my $setter_name = $setter->{'name'}; | 
| 599 |  |  |  |  |  |  |  | 
| 600 |  |  |  |  |  |  | # only do this for the shallowest method with the | 
| 601 |  |  |  |  |  |  | # same name: the others are overrided | 
| 602 | 1852 | 100 |  |  |  | 2817 | if ( not $seen{$setter_name} ) { | 
| 603 | 1737 |  |  |  |  | 2337 | $seen{$setter_name}++; | 
| 604 | 1737 |  |  |  |  | 2582 | my $output = $self->_get_clonable_output($setter); | 
| 605 | 1737 |  |  |  |  | 3431 | $setter->{'code'}->($clone,$output); | 
| 606 |  |  |  |  |  |  | } | 
| 607 |  |  |  |  |  |  | } | 
| 608 | 109 |  |  |  |  | 995 | return $clone; | 
| 609 |  |  |  |  |  |  | } | 
| 610 |  |  |  |  |  |  |  | 
| 611 |  |  |  |  |  |  | sub _get_clonable_output { | 
| 612 | 1852 |  |  | 1852 |  | 2426 | my ( $self, $setter ) = @_; | 
| 613 | 1852 |  |  |  |  | 2217 | my $setter_name = $setter->{'name'}; | 
| 614 |  |  |  |  |  |  |  | 
| 615 |  |  |  |  |  |  | # assume getter/setter symmetry | 
| 616 | 1852 |  |  |  |  | 2112 | my $getter_name = $setter_name; | 
| 617 | 1852 |  |  |  |  | 8105 | $getter_name =~ s/^(_?)set_/$1get_/; | 
| 618 | 1852 |  |  |  |  | 3835 | my $fqn = $setter->{'package'} . '::' . $getter_name; | 
| 619 |  |  |  |  |  |  |  | 
| 620 |  |  |  |  |  |  | # get the code reference for the fully qualified name of the getter | 
| 621 | 1852 |  |  |  |  | 3714 | my $getter = $mop->get_method($fqn); | 
| 622 |  |  |  |  |  |  |  | 
| 623 |  |  |  |  |  |  | # pass the output of the getter to the input of the setter | 
| 624 | 1852 |  |  |  |  | 3384 | my $output = $getter->($self); | 
| 625 | 1852 |  |  |  |  | 3370 | return $output; | 
| 626 |  |  |  |  |  |  | } | 
| 627 |  |  |  |  |  |  |  | 
| 628 |  |  |  |  |  |  | =begin comment | 
| 629 |  |  |  |  |  |  |  | 
| 630 |  |  |  |  |  |  | Invocant destructor. | 
| 631 |  |  |  |  |  |  |  | 
| 632 |  |  |  |  |  |  | Type    : Destructor | 
| 633 |  |  |  |  |  |  | Title   : DESTROY | 
| 634 |  |  |  |  |  |  | Usage   : $phylo->DESTROY | 
| 635 |  |  |  |  |  |  | Function: Destroys Phylo object | 
| 636 |  |  |  |  |  |  | Alias   : | 
| 637 |  |  |  |  |  |  | Returns : TRUE | 
| 638 |  |  |  |  |  |  | Args    : none | 
| 639 |  |  |  |  |  |  | Comments: You don't really need this, | 
| 640 |  |  |  |  |  |  | it is called automatically when | 
| 641 |  |  |  |  |  |  | the object goes out of scope. | 
| 642 |  |  |  |  |  |  |  | 
| 643 |  |  |  |  |  |  | =end comment | 
| 644 |  |  |  |  |  |  |  | 
| 645 |  |  |  |  |  |  | =cut | 
| 646 |  |  |  |  |  |  |  | 
| 647 |  |  |  |  |  |  | sub DESTROY { | 
| 648 | 12044 |  |  | 12044 |  | 124275 | my $self = shift; | 
| 649 |  |  |  |  |  |  |  | 
| 650 |  |  |  |  |  |  | # delete from get_obj_by_id | 
| 651 | 12044 |  |  |  |  | 13760 | my $id; | 
| 652 | 12044 | 50 |  |  |  | 20754 | if ( defined( $id = $self->get_id ) ) { | 
| 653 | 12044 |  |  |  |  | 24174 | delete $objects{$id}; | 
| 654 |  |  |  |  |  |  | } | 
| 655 |  |  |  |  |  |  |  | 
| 656 |  |  |  |  |  |  | # do the cleanups | 
| 657 |  |  |  |  |  |  | # 		my @destructors = @{ $mop->get_destructors( $self ) }; | 
| 658 |  |  |  |  |  |  | # 		for my $d ( @destructors ) { | 
| 659 |  |  |  |  |  |  | # 			$d->{'code'}->( $self ); | 
| 660 |  |  |  |  |  |  | # 		} | 
| 661 | 12044 |  |  |  |  | 14339 | my @classes = @{ $mop->get_classes($self) }; | 
|  | 12044 |  |  |  |  | 28021 |  | 
| 662 | 12044 |  |  |  |  | 18774 | for my $class ( @classes ) { | 
| 663 | 110820 |  |  |  |  | 163302 | my $cleanup = "${class}::_cleanup"; | 
| 664 | 110820 | 100 |  |  |  | 344573 | if ( $class->can($cleanup) ) { | 
| 665 | 77757 |  |  |  |  | 159194 | $self->$cleanup; | 
| 666 |  |  |  |  |  |  | } | 
| 667 |  |  |  |  |  |  | } | 
| 668 |  |  |  |  |  |  |  | 
| 669 |  |  |  |  |  |  | # unregister from mediator | 
| 670 | 12044 |  |  |  |  | 31833 | $taxamediator->unregister( $self ); | 
| 671 |  |  |  |  |  |  |  | 
| 672 |  |  |  |  |  |  | # done cleaning up, id can be reclaimed | 
| 673 | 12044 |  |  |  |  | 23481 | Bio::Phylo::Util::IDPool->_reclaim( $self ); | 
| 674 |  |  |  |  |  |  | } | 
| 675 |  |  |  |  |  |  |  | 
| 676 |  |  |  |  |  |  |  | 
| 677 |  |  |  |  |  |  | # child classes probably should have a method like this, | 
| 678 |  |  |  |  |  |  | # if their objects hold internal state anyway (b/c they'll | 
| 679 |  |  |  |  |  |  | # be inside-out objects). | 
| 680 |  |  |  |  |  |  | sub _cleanup : Destructor { | 
| 681 | 12044 |  |  | 12044 |  | 14703 | my $self = shift; | 
| 682 | 12044 |  |  |  |  | 19792 | my $id = $self->get_id; | 
| 683 |  |  |  |  |  |  |  | 
| 684 |  |  |  |  |  |  | # cleanup local fields | 
| 685 | 12044 | 50 |  |  |  | 21372 | if ( defined $id ) { | 
| 686 | 12044 |  |  |  |  | 16980 | for my $field (@fields) { | 
| 687 | 84308 |  |  |  |  | 108607 | delete $field->{$id}; | 
| 688 |  |  |  |  |  |  | } | 
| 689 |  |  |  |  |  |  | } | 
| 690 | 57 |  |  | 57 |  | 49170 | } | 
|  | 57 |  |  |  |  | 135 |  | 
|  | 57 |  |  |  |  | 251 |  | 
| 691 |  |  |  |  |  |  |  | 
| 692 |  |  |  |  |  |  | =begin comment | 
| 693 |  |  |  |  |  |  |  | 
| 694 |  |  |  |  |  |  | Type    : Internal method | 
| 695 |  |  |  |  |  |  | Title   : _get_container | 
| 696 |  |  |  |  |  |  | Usage   : $phylo->_get_container; | 
| 697 |  |  |  |  |  |  | Function: Retrieves the object that contains the invocant (e.g. for a node, | 
| 698 |  |  |  |  |  |  | returns the tree it is in). | 
| 699 |  |  |  |  |  |  | Returns : Bio::Phylo::* object | 
| 700 |  |  |  |  |  |  | Args    : None | 
| 701 |  |  |  |  |  |  |  | 
| 702 |  |  |  |  |  |  | =end comment | 
| 703 |  |  |  |  |  |  |  | 
| 704 |  |  |  |  |  |  | =cut | 
| 705 |  |  |  |  |  |  |  | 
| 706 |  |  |  |  |  |  | # this is the converse of $listable->get_entities, i.e. | 
| 707 |  |  |  |  |  |  | # every entity in a listable object holds a reference | 
| 708 |  |  |  |  |  |  | # to its container. We actually use this surprisingly | 
| 709 |  |  |  |  |  |  | # rarely, and because I read somewhere (heh) it's bad | 
| 710 |  |  |  |  |  |  | # to have the objects of a has-a relationship fiddle with | 
| 711 |  |  |  |  |  |  | # their container we hide this method from abuse. Then | 
| 712 |  |  |  |  |  |  | # again, sometimes it's handy ;-) | 
| 713 | 907 |  |  | 907 |  | 1647 | sub _get_container { $container{ shift->get_id } } | 
| 714 |  |  |  |  |  |  |  | 
| 715 |  |  |  |  |  |  | =begin comment | 
| 716 |  |  |  |  |  |  |  | 
| 717 |  |  |  |  |  |  | Type    : Internal method | 
| 718 |  |  |  |  |  |  | Title   : _set_container | 
| 719 |  |  |  |  |  |  | Usage   : $phylo->_set_container($obj); | 
| 720 |  |  |  |  |  |  | Function: Creates a reference from the invocant to the object that contains | 
| 721 |  |  |  |  |  |  | it (e.g. for a node, creates a reference to the tree it is in). | 
| 722 |  |  |  |  |  |  | Returns : Bio::Phylo::* object | 
| 723 |  |  |  |  |  |  | Args    : A Bio::Phylo::Listable object | 
| 724 |  |  |  |  |  |  |  | 
| 725 |  |  |  |  |  |  | =end comment | 
| 726 |  |  |  |  |  |  |  | 
| 727 |  |  |  |  |  |  | =cut | 
| 728 |  |  |  |  |  |  |  | 
| 729 |  |  |  |  |  |  | sub _set_container { | 
| 730 | 17319 |  |  | 17319 |  | 26520 | my ( $self, $container ) = @_; | 
| 731 | 17319 |  |  |  |  | 27647 | my $id = $self->get_id; | 
| 732 | 17319 | 50 |  |  |  | 43003 | if ( blessed $container ) { | 
| 733 | 17319 | 50 |  |  |  | 39999 | if ( $container->can('can_contain') ) { | 
| 734 | 17319 | 50 |  |  |  | 29332 | if ( $container->can_contain($self) ) { | 
| 735 | 17319 | 50 |  |  |  | 34780 | if ( $container->contains($self) ) { | 
| 736 | 17319 |  |  |  |  | 32234 | $container{$id} = $container; | 
| 737 | 17319 |  |  |  |  | 40332 | weaken( $container{$id} ); | 
| 738 |  |  |  |  |  |  | } | 
| 739 |  |  |  |  |  |  | else { | 
| 740 | 0 |  |  |  |  | 0 | throw 'ObjectMismatch' => "'$self' not in '$container'"; | 
| 741 |  |  |  |  |  |  | } | 
| 742 |  |  |  |  |  |  | } | 
| 743 |  |  |  |  |  |  | else { | 
| 744 | 0 |  |  |  |  | 0 | throw 'ObjectMismatch' => | 
| 745 |  |  |  |  |  |  | "'$container' cannot contain '$self'"; | 
| 746 |  |  |  |  |  |  | } | 
| 747 |  |  |  |  |  |  | } | 
| 748 |  |  |  |  |  |  | else { | 
| 749 | 0 |  |  |  |  | 0 | throw 'ObjectMismatch' => "Invalid objects"; | 
| 750 |  |  |  |  |  |  | } | 
| 751 |  |  |  |  |  |  | } | 
| 752 |  |  |  |  |  |  | else { | 
| 753 | 0 |  |  |  |  | 0 | delete $container{$id}; | 
| 754 |  |  |  |  |  |  | #throw 'BadArgs' => "Argument not an object"; | 
| 755 |  |  |  |  |  |  | } | 
| 756 | 17319 |  |  |  |  | 34715 | return $self; | 
| 757 |  |  |  |  |  |  | } | 
| 758 |  |  |  |  |  |  |  | 
| 759 |  |  |  |  |  |  | =item to_js() | 
| 760 |  |  |  |  |  |  |  | 
| 761 |  |  |  |  |  |  | Serializes to simple JSON. For a conversion to NeXML/JSON, use C. | 
| 762 |  |  |  |  |  |  |  | 
| 763 |  |  |  |  |  |  | Type    : Serializer | 
| 764 |  |  |  |  |  |  | Title   : to_js | 
| 765 |  |  |  |  |  |  | Usage   : my $json = $object->to_js; | 
| 766 |  |  |  |  |  |  | Function: Serializes to JSON | 
| 767 |  |  |  |  |  |  | Returns : A JSON string | 
| 768 |  |  |  |  |  |  | Args    : None. | 
| 769 |  |  |  |  |  |  | Comments: | 
| 770 |  |  |  |  |  |  |  | 
| 771 |  |  |  |  |  |  | =cut | 
| 772 |  |  |  |  |  |  |  | 
| 773 | 0 | 0 |  | 0 | 1 |  | sub to_js {JSON::to_json(shift->_json_data,{'pretty'=>1}) if looks_like_class 'JSON'} | 
| 774 |  |  |  |  |  |  |  | 
| 775 |  |  |  |  |  |  | sub _json_data { | 
| 776 | 0 |  |  | 0 |  |  | my $self = shift; | 
| 777 | 0 |  |  |  |  |  | my %data = %{ $self->get_generic }; | 
|  | 0 |  |  |  |  |  |  | 
| 778 | 0 | 0 |  |  |  |  | $data{'guid'}  = $self->get_guid if $self->get_guid; | 
| 779 | 0 | 0 |  |  |  |  | $data{'desc'}  = $self->get_desc if $self->get_desc; | 
| 780 | 0 | 0 |  |  |  |  | $data{'score'} = $self->get_score if $self->get_score; | 
| 781 | 0 |  |  |  |  |  | return \%data; | 
| 782 |  |  |  |  |  |  | } | 
| 783 |  |  |  |  |  |  |  | 
| 784 |  |  |  |  |  |  | =back | 
| 785 |  |  |  |  |  |  |  | 
| 786 |  |  |  |  |  |  | =head1 SEE ALSO | 
| 787 |  |  |  |  |  |  |  | 
| 788 |  |  |  |  |  |  | There is a mailing list at L | 
| 789 |  |  |  |  |  |  | for any user or developer questions and discussions. | 
| 790 |  |  |  |  |  |  |  | 
| 791 |  |  |  |  |  |  | Also see the manual: L and L | 
| 792 |  |  |  |  |  |  |  | 
| 793 |  |  |  |  |  |  | =head1 CITATION | 
| 794 |  |  |  |  |  |  |  | 
| 795 |  |  |  |  |  |  | If you use Bio::Phylo in published research, please cite it: | 
| 796 |  |  |  |  |  |  |  | 
| 797 |  |  |  |  |  |  | B, B, B, B | 
| 798 |  |  |  |  |  |  | and B, 2011. Bio::Phylo - phyloinformatic analysis using Perl. | 
| 799 |  |  |  |  |  |  | I B<12>:63. | 
| 800 |  |  |  |  |  |  | L | 
| 801 |  |  |  |  |  |  |  | 
| 802 |  |  |  |  |  |  | =cut | 
| 803 |  |  |  |  |  |  |  | 
| 804 |  |  |  |  |  |  | } | 
| 805 |  |  |  |  |  |  | 1; |