[BioRuby] Bio::Tree#children IndexError when called on a root node which does not have children.

Naohisa GOTO ngoto at gen-info.osaka-u.ac.jp
Sun Jul 12 08:46:26 UTC 2009


Hi Diana,

On Sat, 11 Jul 2009 22:18:12 -0400
Diana Jaunzeikare <rozziite at gmail.com> wrote:

> Hi all,
> 
> While i was writing parser for Phyloxml I discovered such behavior in
> Bio::Tree class.
> 
> Bio::Tree#children method gives IndexError if it is called on a root node
> which does not have children.
> 
> irb(main):002:0> tree = Bio::Tree.new
> => #<Bio::Tree:0xb7d759e4 @root=nil, @pathway=#<Bio::Pathway:0xb7c490e8
> @graph={}, @relations=[], @label={}, @undirected=true, @index={}>,
> @options={}>
>  irb(main):004:0> node = Bio::Tree::Node.new
> => (Node:b7c43f80)
> irb(main):005:0> node.name = "node1"
> => "node1"
> irb(main):006:0> tree.root = node
>  => (Node:"node1")
> irb(main):007:0> tree.children(tree.root)
> IndexError: node1 not found
>     from /usr/local/lib/site_ruby/1.8/bio/tree.rb:591:in `path'
>     from /usr/local/lib/site_ruby/1.8/bio/tree.rb:640:in `children'
>      from (irb):7
> irb(main):008:0>

The error shows that "tree.root" does not exist in the tree.

Currently, Bio::Tree#root=(node) does not check whether
the specified node exists in the tree or not, and it changes
only the internal pointer to the root. In addition, it does
not modify the tree except the pointer to the root.

In this case, the node should be added to the tree.

Before "tree.root = node" or "tree.children(tree.root)",
    tree.add_node(node)
is needed.

Why the latter case works is that Bio::Tree#add_edge
automatically adds nodes if the nodes do not exist in the tree.

> 
> 
> If the children method is called on other than root node (which does not
> have children), then it correctly gives empty array:
> 
> irb(main):008:0> node2 = Bio::Tree::Node.new
> => (Node:b7c3b088)
> irb(main):009:0> node2.name = "node2"
> => "node2"
> irb(main):010:0> tree.add_node(node2)
> => #<Bio::Tree:0xb7d759e4 @root=(Node:"node1"),
> @pathway=#<Bio::Pathway:0xb7c490e8 @graph={(Node:"node2")=>{}},
> @relations=[], @label={}, @undirected=true, @index={}>, @options={}>
> irb(main):011:0> tree.add_edge(tree.root, node2)
> => <Edge distance=nil>
> irb(main):012:0> tree.children(node2)
> => []
> irb(main):013:0>
> 
> If the root node has children, then everything is fine:
> 
>  irb(main):013:0> tree.children(tree.root)
> => [(Node:"node2")]
> 
> 
> Diana
> 


-- 
Naohisa Goto
ngoto at gen-info.osaka-u.ac.jp / ng at bioruby.org



More information about the BioRuby mailing list