rubytree 0.6.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +2 -2
- data/ChangeLog +26 -1
- data/History.txt +5 -1
- data/README +31 -20
- data/Rakefile +17 -3
- data/TODO +6 -1
- data/lib/tree.rb +205 -126
- data/lib/tree/binarytree.rb +28 -23
- data/test/test_binarytree.rb +3 -3
- data/test/test_tree.rb +24 -21
- metadata +41 -9
    
        data/COPYING
    CHANGED
    
    | @@ -2,7 +2,7 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            http://rubytree.rubyforge.org
         | 
| 4 4 |  | 
| 5 | 
            -
            Copyright (c) 2006 | 
| 5 | 
            +
            Copyright (c) 2006, 2007, 2008, 2009, 2010 Anupam Sengupta (anupamsg at gmail dot com)
         | 
| 6 6 |  | 
| 7 7 | 
             
            All rights reserved.
         | 
| 8 8 |  | 
| @@ -26,4 +26,4 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSE | |
| 26 26 | 
             
            WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
         | 
| 27 27 | 
             
            THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
         | 
| 28 28 |  | 
| 29 | 
            -
            $Id | 
| 29 | 
            +
            $Id$
         | 
    
        data/ChangeLog
    CHANGED
    
    | @@ -1,3 +1,28 @@ | |
| 1 | 
            +
            2010-01-30  Anupam Sengupta  <anupamsg@gmail.com>
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            	* lib/tree.rb (Tree): Update the example code to use Ruby
         | 
| 4 | 
            +
            	conventions for the variable names.
         | 
| 5 | 
            +
            	(Tree): updated the documentation.
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            	* README: Updated the example to use Ruby conventions for the
         | 
| 8 | 
            +
            	variable names.
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            2010-01-28  Anupam Sengupta  <anupamsg@gmail.com>
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            	* Rakefile: Minor documentation change.
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            	* README (DOCUMENTATION): Added comments to the example code.
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            	* test/test_tree.rb: Documentation clean up.
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            	* test/test_binarytree.rb: Documentation clean up.
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            	* lib/tree.rb (Tree): Cleaned up documentation.  Also some minor
         | 
| 21 | 
            +
            	code refactoring done.
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            	* lib/tree/binarytree.rb (Tree): Cleaned up documentation.  Minor
         | 
| 24 | 
            +
            	readability improvement in the isLeftChild? and isRightChild? methods.
         | 
| 25 | 
            +
             | 
| 1 26 | 
             
            2010-01-05  Anupam Sengupta  <anupamsg@gmail.com>
         | 
| 2 27 |  | 
| 3 28 | 
             
            	* README: Updated the requirements section.
         | 
| @@ -207,4 +232,4 @@ | |
| 207 232 |  | 
| 208 233 | 
             
            	* Changelog: Added the Changelog file.
         | 
| 209 234 |  | 
| 210 | 
            -
            $Id | 
| 235 | 
            +
            $Id$
         | 
    
        data/History.txt
    CHANGED
    
    | @@ -1,3 +1,7 @@ | |
| 1 | 
            +
            === 0.6.2 / 2010-01-30
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            * Updated the documentation.
         | 
| 4 | 
            +
             | 
| 1 5 | 
             
            === 0.6.1 / 2010-01-04
         | 
| 2 6 |  | 
| 3 7 | 
             
            * Changed the hard-dependency on the 'structured_warnings' RubyGem to a soft-dependency - which lets Rubytree still
         | 
| @@ -40,4 +44,4 @@ | |
| 40 44 |  | 
| 41 45 | 
             
            * Minor code refactoring. Changes in the Rakefile.
         | 
| 42 46 |  | 
| 43 | 
            -
            $Id | 
| 47 | 
            +
            $Id$
         | 
    
        data/README
    CHANGED
    
    | @@ -6,15 +6,16 @@ | |
| 6 6 | 
             
             \/ \_/\__,_|_.__/ \__, |\__|_|  \___|\___|
         | 
| 7 7 | 
             
                              |___/
         | 
| 8 8 |  | 
| 9 | 
            -
              (c) 2006, 2007, 2008, 2009, 2010 Anupam Sengupta
         | 
| 9 | 
            +
              Copyright (c) 2006, 2007, 2008, 2009, 2010 Anupam Sengupta (anupamsg at gmail dot com)
         | 
| 10 10 | 
             
              http://rubytree.rubyforge.org
         | 
| 11 11 |  | 
| 12 12 | 
             
            == DESCRIPTION:
         | 
| 13 13 |  | 
| 14 | 
            -
            RubyTree is a Ruby implementation of the generic  | 
| 15 | 
            -
             | 
| 16 | 
            -
            the tree are the primary  | 
| 17 | 
            -
             | 
| 14 | 
            +
            RubyTree is a Ruby implementation of the generic tree data structure.  It provides a node-based model to store keyed
         | 
| 15 | 
            +
            node-elements in the tree and simple APIs to access, modify and traverse the structure.  RubyTree is node-centric, where
         | 
| 16 | 
            +
            individual nodes on the tree are the primary compositional and structural elements.
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            This implementation also mixes in the Enumerable module to allow standard access to the tree as a collection.
         | 
| 18 19 |  | 
| 19 20 | 
             
            == SYNOPSIS:
         | 
| 20 21 |  | 
| @@ -34,24 +35,34 @@ As an example, the following code-snippet implements this tree structure: | |
| 34 35 | 
             
             | GRANDCHILD 1  |
         | 
| 35 36 | 
             
             +---------------+
         | 
| 36 37 |  | 
| 37 | 
            -
             # Example
         | 
| 38 | 
            -
             require 'tree'
         | 
| 38 | 
            +
             # ..... Example starts.
         | 
| 39 | 
            +
             require 'tree'                 # Load the library
         | 
| 40 | 
            +
             | 
| 41 | 
            +
             # ..... Create the root node first.  Note that every node has a name and an optional content payload.
         | 
| 42 | 
            +
             root_node = Tree::TreeNode.new("ROOT", "Root Content")
         | 
| 43 | 
            +
             | 
| 44 | 
            +
             # ..... Now insert the child nodes.  Note that you can "chain" the child insertions for a given path to any depth.
         | 
| 45 | 
            +
             root_node << Tree::TreeNode.new("CHILD1", "Child1 Content") << Tree::TreeNode.new("GRANDCHILD1", "GrandChild1 Content")
         | 
| 46 | 
            +
             root_node << Tree::TreeNode.new("CHILD2", "Child2 Content")
         | 
| 47 | 
            +
             | 
| 48 | 
            +
             # ..... Lets print the representation to stdout.  This is primarily used for debugging purposes.
         | 
| 49 | 
            +
             root_node.printTree
         | 
| 39 50 |  | 
| 40 | 
            -
              | 
| 41 | 
            -
              | 
| 42 | 
            -
              | 
| 51 | 
            +
             # ..... Lets directly access children and grandchildren of the root.  The can be "chained" for a given path to any depth.
         | 
| 52 | 
            +
             child1 = root_node["CHILD1"]
         | 
| 53 | 
            +
             grand_child1 = root_node["CHILD1"]["GRANDCHILD1"]
         | 
| 43 54 |  | 
| 44 | 
            -
              | 
| 55 | 
            +
             # ..... Now lets retrieve siblings of the current node as an array.
         | 
| 56 | 
            +
             siblings_of_child1 = child1.siblings
         | 
| 45 57 |  | 
| 46 | 
            -
              | 
| 47 | 
            -
              | 
| 58 | 
            +
             # ..... Lets retrieve immediate children of the root node as an array.
         | 
| 59 | 
            +
             children_of_root = root_node.children
         | 
| 48 60 |  | 
| 49 | 
            -
              | 
| 50 | 
            -
              | 
| 61 | 
            +
             # ..... This is a depth-first and L-to-R pre-ordered traversal.
         | 
| 62 | 
            +
             root_node.each { |node| node.content.reverse }
         | 
| 51 63 |  | 
| 52 | 
            -
             #  | 
| 53 | 
            -
              | 
| 54 | 
            -
             myTreeRoot.remove!(child1) # Remove the child
         | 
| 64 | 
            +
             # ..... Lets remove a child node from the root node.
         | 
| 65 | 
            +
             root_node.remove!(child1)
         | 
| 55 66 |  | 
| 56 67 |  | 
| 57 68 | 
             
            == REQUIREMENTS:
         | 
| @@ -127,7 +138,7 @@ tasks. | |
| 127 138 |  | 
| 128 139 | 
             
            RubyTree is licensed under the BSD[http://www.opensource.org/licenses/bsd-license.php] license.
         | 
| 129 140 |  | 
| 130 | 
            -
            Copyright (c) 2006, 2007 Anupam Sengupta
         | 
| 141 | 
            +
            Copyright (c) 2006, 2007, 2008, 2009, 2010 Anupam Sengupta
         | 
| 131 142 | 
             
            All rights reserved.
         | 
| 132 143 |  | 
| 133 144 | 
             
            Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
         | 
| @@ -151,4 +162,4 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS | |
| 151 162 | 
             
            THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
         | 
| 152 163 |  | 
| 153 164 |  | 
| 154 | 
            -
            (Document Revision: $Revision | 
| 165 | 
            +
            (Document Revision: $Revision$ by $Author$)
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -1,10 +1,10 @@ | |
| 1 1 | 
             
            # -*- mode: ruby; -*-
         | 
| 2 2 | 
             
            #
         | 
| 3 | 
            -
            # Rakefile
         | 
| 3 | 
            +
            # Rakefile - This file is part of the RubyTree package.
         | 
| 4 4 | 
             
            #
         | 
| 5 | 
            -
            # $Revision | 
| 5 | 
            +
            # $Revision$ by $Author$ on $Date$
         | 
| 6 6 | 
             
            #
         | 
| 7 | 
            -
            # Copyright (c) 2006, 2007 Anupam Sengupta
         | 
| 7 | 
            +
            # Copyright (c) 2006, 2007, 2009, 2010  Anupam Sengupta
         | 
| 8 8 | 
             
            #
         | 
| 9 9 | 
             
            # All rights reserved.
         | 
| 10 10 | 
             
            #
         | 
| @@ -61,6 +61,20 @@ begin | |
| 61 61 | 
             
                self.need_tar                   = true
         | 
| 62 62 | 
             
                self.need_zip                   = true
         | 
| 63 63 |  | 
| 64 | 
            +
                # Post installation message
         | 
| 65 | 
            +
                self.post_install_message       = <<MSGEND
         | 
| 66 | 
            +
            ========================================================================
         | 
| 67 | 
            +
             | 
| 68 | 
            +
             Thank you for installing #{PKG_NAME.capitalize}.
         | 
| 69 | 
            +
             | 
| 70 | 
            +
             Please note that a few APIs have been deprecated since Version 0.6.1
         | 
| 71 | 
            +
             | 
| 72 | 
            +
             Specifically, the 'Tree::TreeNode#depth' method is now deprecated, and
         | 
| 73 | 
            +
             a new nodeDepth() method has been introduced.
         | 
| 74 | 
            +
             | 
| 75 | 
            +
            ========================================================================
         | 
| 76 | 
            +
            MSGEND
         | 
| 77 | 
            +
             | 
| 64 78 | 
             
                # Code Metrics ...
         | 
| 65 79 | 
             
                self.flay_threshold             = timebomb 1200, 100 # Default is 1200, 100
         | 
| 66 80 | 
             
                self.flog_threshold             = timebomb 1200, 100 # Default is 1200, 100
         | 
    
        data/TODO
    CHANGED
    
    | @@ -1,5 +1,10 @@ | |
| 1 1 | 
             
            # -*- mode: org; coding: utf-8-unix; -*-
         | 
| 2 2 |  | 
| 3 | 
            +
            * TODO Convert all method names to the canonical /^[_a-z<>=\[|+-\/\*`]+[_a-z0-9_<>=~@\[\]]*[=!\?]?$/ pattern
         | 
| 4 | 
            +
              See Roodi report at http://getcaliper.com/caliper/tool?tool=roodi&repo=git://github.com/evolve75/RubyTree.git
         | 
| 5 | 
            +
            * TODO Fix the TreeNode#root method to return nil for root's root.
         | 
| 6 | 
            +
            * TODO Fix the marshal_load method.  This probably needs to be a class method.
         | 
| 7 | 
            +
            * TODO Fix the semantic inconsistency between the TreeNode#first|lastSibling method and the siblings method w.r.t. the root
         | 
| 3 8 | 
             
            * TODO Create the basic UML diagrams and upload to the Site
         | 
| 4 9 | 
             
              DEADLINE: <2010-01-04 Mon>
         | 
| 5 10 |  | 
| @@ -16,4 +21,4 @@ | |
| 16 21 |  | 
| 17 22 |  | 
| 18 23 |  | 
| 19 | 
            -
            $Id | 
| 24 | 
            +
            $Id$
         | 
    
        data/lib/tree.rb
    CHANGED
    
    | @@ -1,11 +1,11 @@ | |
| 1 | 
            -
            # tree.rb
         | 
| 1 | 
            +
            # tree.rb - This file is part of the RubyTree package.
         | 
| 2 2 | 
             
            #
         | 
| 3 | 
            -
            # $Revision | 
| 3 | 
            +
            # $Revision$ by $Author$ on $Date$
         | 
| 4 4 | 
             
            #
         | 
| 5 | 
            -
            # = tree.rb - Generic  | 
| 5 | 
            +
            # = tree.rb - Generic implementation of an N-ary tree data structure.
         | 
| 6 6 | 
             
            #
         | 
| 7 7 | 
             
            # Provides a generic tree data structure with ability to
         | 
| 8 | 
            -
            # store keyed node elements in the tree.  | 
| 8 | 
            +
            # store keyed node elements in the tree.  This implementation
         | 
| 9 9 | 
             
            # mixes in the Enumerable module.
         | 
| 10 10 | 
             
            #
         | 
| 11 11 | 
             
            # Author:: Anupam Sengupta (anupamsg@gmail.com)
         | 
| @@ -41,29 +41,42 @@ | |
| 41 41 | 
             
            # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
         | 
| 42 42 | 
             
            #
         | 
| 43 43 |  | 
| 44 | 
            -
            # This module provides a TreeNode class which is the primary class for  | 
| 45 | 
            -
            # nodes  | 
| 46 | 
            -
            # | 
| 44 | 
            +
            # This module provides a TreeNode class which is the primary class for representing
         | 
| 45 | 
            +
            # nodes in the tree.
         | 
| 46 | 
            +
            #
         | 
| 47 | 
            +
            # This module mixes in the Enumerable module, and also acts as the namespace for all
         | 
| 48 | 
            +
            # classes in RubyTree.
         | 
| 47 49 | 
             
            module Tree
         | 
| 48 50 |  | 
| 49 51 | 
             
              # Rubytree Package Version
         | 
| 50 | 
            -
              VERSION = '0.6. | 
| 52 | 
            +
              VERSION = '0.6.2'
         | 
| 51 53 |  | 
| 52 54 | 
             
              # == TreeNode Class Description
         | 
| 53 55 | 
             
              #
         | 
| 54 | 
            -
              #  | 
| 55 | 
            -
              # place-holder for the node data (i.e.,  | 
| 56 | 
            -
              # names are required to be unique | 
| 57 | 
            -
              # | 
| 56 | 
            +
              # This class models the nodes for an N-ary tree data structue. The nodes are +named+
         | 
| 57 | 
            +
              # and have a place-holder for the node data (i.e., `content' of the node). The node
         | 
| 58 | 
            +
              # names are required to be *unique* within the tree.
         | 
| 59 | 
            +
              #
         | 
| 60 | 
            +
              # The node content is not required to be unique across different nodes in the tree, and
         | 
| 61 | 
            +
              # can be +nil+ as well.
         | 
| 62 | 
            +
              #
         | 
| 63 | 
            +
              # The class provides various traversal methods to navigate the tree,
         | 
| 64 | 
            +
              # methods to modify contents of the node or to change position of the node in the tree
         | 
| 65 | 
            +
              # and methods to change structure of the tree.
         | 
| 58 66 | 
             
              #
         | 
| 59 | 
            -
              # A node can have any number of child nodes attached to it | 
| 60 | 
            -
              #  | 
| 61 | 
            -
              #  | 
| 67 | 
            +
              # A node can have any number of child nodes attached to it and hence can be used to create N-ary trees.
         | 
| 68 | 
            +
              # Access to the child nodes can be made in order (with the conventional left to right access), or
         | 
| 69 | 
            +
              # randomly.
         | 
| 70 | 
            +
              #
         | 
| 71 | 
            +
              # The node also provides direct access to its parent and other superior parents in the path to
         | 
| 72 | 
            +
              # root of the tree.  In addition, a node can also access its sibling nodes, if present.
         | 
| 73 | 
            +
              # Note that while this implementation does not explicitly support directed graphs, the class itself makes
         | 
| 74 | 
            +
              # no restrictions on associating a node's +CONTENT+ with multiple nodes in the tree.
         | 
| 62 75 | 
             
              #
         | 
| 63 76 | 
             
              #
         | 
| 64 77 | 
             
              # == Example
         | 
| 65 78 | 
             
              #
         | 
| 66 | 
            -
              #  The following  | 
| 79 | 
            +
              #  The following example implements this tree structure:
         | 
| 67 80 | 
             
              #
         | 
| 68 81 | 
             
              #                    +------------+
         | 
| 69 82 | 
             
              #                    |    ROOT    |
         | 
| @@ -81,36 +94,38 @@ module Tree | |
| 81 94 | 
             
              #
         | 
| 82 95 | 
             
              # require 'tree'
         | 
| 83 96 | 
             
              #
         | 
| 84 | 
            -
              #  | 
| 97 | 
            +
              # root_node = Tree::TreeNode.new("ROOT", "Root Content")
         | 
| 85 98 | 
             
              #
         | 
| 86 | 
            -
              #  | 
| 99 | 
            +
              # root_node << Tree::TreeNode.new("CHILD1", "Child1 Content") << Tree::TreeNode.new("GRANDCHILD1", "GrandChild1 Content")
         | 
| 87 100 | 
             
              #
         | 
| 88 | 
            -
              #  | 
| 101 | 
            +
              # root_node << Tree::TreeNode.new("CHILD2", "Child2 Content")
         | 
| 89 102 | 
             
              #
         | 
| 90 | 
            -
              #  | 
| 103 | 
            +
              # root_node.printTree
         | 
| 91 104 | 
             
              #
         | 
| 92 | 
            -
              # child1 | 
| 105 | 
            +
              # child1       = root_node["CHILD1"]
         | 
| 93 106 | 
             
              #
         | 
| 94 | 
            -
              #  | 
| 107 | 
            +
              # grand_child1 = root_node["CHILD1"]["GRANDCHILD1"]
         | 
| 95 108 | 
             
              #
         | 
| 96 | 
            -
              #  | 
| 109 | 
            +
              # siblings_of_child1 = child1.siblings
         | 
| 97 110 | 
             
              #
         | 
| 98 | 
            -
              #  | 
| 111 | 
            +
              # children_of_root   = root_node.children
         | 
| 99 112 | 
             
              #
         | 
| 100 113 | 
             
              # # Process all nodes
         | 
| 101 114 | 
             
              #
         | 
| 102 | 
            -
              #  | 
| 115 | 
            +
              # root_node.each { |node| node.content.reverse }
         | 
| 103 116 | 
             
              #
         | 
| 104 | 
            -
              #  | 
| 117 | 
            +
              # root_node.remove!(child1) # Remove the child
         | 
| 105 118 | 
             
              #
         | 
| 106 119 | 
             
              class TreeNode
         | 
| 107 120 | 
             
                include Enumerable
         | 
| 108 121 |  | 
| 109 | 
            -
                # Name of this  | 
| 122 | 
            +
                # Name of this node.  Expected to be unique within the tree.
         | 
| 110 123 | 
             
                attr_reader   :name
         | 
| 111 | 
            -
             | 
| 124 | 
            +
             | 
| 125 | 
            +
                # Content of this node.  Can be +nil+.
         | 
| 112 126 | 
             
                attr_accessor :content
         | 
| 113 | 
            -
             | 
| 127 | 
            +
             | 
| 128 | 
            +
                # Parent of this node.  Will be +nil+ for root nodes.
         | 
| 114 129 | 
             
                attr_reader   :parent
         | 
| 115 130 |  | 
| 116 131 |  | 
| @@ -128,8 +143,8 @@ module Tree | |
| 128 143 | 
             
                  @children = []
         | 
| 129 144 | 
             
                end
         | 
| 130 145 |  | 
| 131 | 
            -
                # Returns a copy of  | 
| 132 | 
            -
                # its tree.
         | 
| 146 | 
            +
                # Returns a copy of the receiver node, with its parent and children links removed.
         | 
| 147 | 
            +
                # The original node remains attached to its tree.
         | 
| 133 148 | 
             
                def detached_copy
         | 
| 134 149 | 
             
                  Tree::TreeNode.new(@name, @content ? @content.clone : nil)
         | 
| 135 150 | 
             
                end
         | 
| @@ -143,8 +158,10 @@ module Tree | |
| 143 158 | 
             
                    " Total Nodes: #{size()}"
         | 
| 144 159 | 
             
                end
         | 
| 145 160 |  | 
| 146 | 
            -
                # Returns an array of ancestors  | 
| 147 | 
            -
                #  | 
| 161 | 
            +
                # Returns an array of ancestors of the receiver node in reversed order
         | 
| 162 | 
            +
                # (the first element is the immediate parent of the receiver).
         | 
| 163 | 
            +
                #
         | 
| 164 | 
            +
                # Returns +nil+ if the receiver is a root node.
         | 
| 148 165 | 
             
                def parentage
         | 
| 149 166 | 
             
                  return nil if isRoot?
         | 
| 150 167 |  | 
| @@ -158,23 +175,38 @@ module Tree | |
| 158 175 | 
             
                  parentageArray
         | 
| 159 176 | 
             
                end
         | 
| 160 177 |  | 
| 161 | 
            -
                # Protected method to set the parent node.
         | 
| 162 | 
            -
                # This method should NOT be invoked by client code.
         | 
| 163 | 
            -
                 | 
| 178 | 
            +
                # Protected method to set the parent node for the receiver node.
         | 
| 179 | 
            +
                # This method should *NOT* be invoked by client code.
         | 
| 180 | 
            +
                #
         | 
| 181 | 
            +
                # Returns the parent.
         | 
| 182 | 
            +
                def parent=(parent)         # :nodoc:
         | 
| 164 183 | 
             
                  @parent = parent
         | 
| 165 184 | 
             
                end
         | 
| 166 185 |  | 
| 167 | 
            -
                # Convenience synonym for TreeNode#add method. | 
| 168 | 
            -
                # | 
| 186 | 
            +
                # Convenience synonym for TreeNode#add method.
         | 
| 187 | 
            +
                #
         | 
| 188 | 
            +
                # This method allows an easy method to add node hierarchies to the tree
         | 
| 189 | 
            +
                # on a given path via chaining the method calls to successive child nodes.
         | 
| 169 190 | 
             
                #
         | 
| 170 | 
            -
                #  | 
| 191 | 
            +
                # Example: <tt>root << child << grand_child</tt>
         | 
| 192 | 
            +
                #
         | 
| 193 | 
            +
                # Returns the added child node.
         | 
| 171 194 | 
             
                def <<(child)
         | 
| 172 195 | 
             
                  add(child)
         | 
| 173 196 | 
             
                end
         | 
| 174 197 |  | 
| 175 | 
            -
                # Adds the specified child node to the receiver node. | 
| 176 | 
            -
                # | 
| 177 | 
            -
                #  | 
| 198 | 
            +
                # Adds the specified child node to the receiver node.
         | 
| 199 | 
            +
                #
         | 
| 200 | 
            +
                # This method can also be used for *grafting* a subtree into the receiver node's tree, if the specified child node
         | 
| 201 | 
            +
                # is the root of a subtree (i.e., has child nodes under it).
         | 
| 202 | 
            +
                #
         | 
| 203 | 
            +
                # The receiver node becomes parent of the node passed in as the argument, and
         | 
| 204 | 
            +
                # the child is added as the last child ("right most") in the current set of
         | 
| 205 | 
            +
                # children of the receiver node.
         | 
| 206 | 
            +
                #
         | 
| 207 | 
            +
                # Returns the added child node.
         | 
| 208 | 
            +
                #
         | 
| 209 | 
            +
                # An exception is raised if another child node with the same name exists.
         | 
| 178 210 | 
             
                def add(child)
         | 
| 179 211 | 
             
                  raise "Child already added" if @childrenHash.has_key?(child.name)
         | 
| 180 212 |  | 
| @@ -182,12 +214,15 @@ module Tree | |
| 182 214 | 
             
                  @children << child
         | 
| 183 215 | 
             
                  child.parent = self
         | 
| 184 216 | 
             
                  return child
         | 
| 185 | 
            -
             | 
| 186 217 | 
             
                end
         | 
| 187 218 |  | 
| 188 | 
            -
                # Removes the specified child node from the receiver node. | 
| 189 | 
            -
                # | 
| 190 | 
            -
                #  | 
| 219 | 
            +
                # Removes the specified child node from the receiver node.
         | 
| 220 | 
            +
                #
         | 
| 221 | 
            +
                # This method can also be used for *pruning* a subtree, in cases where the removed child node is
         | 
| 222 | 
            +
                # the root of the subtree to be pruned.
         | 
| 223 | 
            +
                #
         | 
| 224 | 
            +
                # The removed child node is orphaned but accessible if an alternate reference exists.  If accesible via
         | 
| 225 | 
            +
                # an alternate reference, the removed child will report itself as a root node for its subtree.
         | 
| 191 226 | 
             
                #
         | 
| 192 227 | 
             
                # Returns the child node.
         | 
| 193 228 | 
             
                def remove!(child)
         | 
| @@ -197,13 +232,18 @@ module Tree | |
| 197 232 | 
             
                  return child
         | 
| 198 233 | 
             
                end
         | 
| 199 234 |  | 
| 200 | 
            -
                # Removes  | 
| 201 | 
            -
                # | 
| 235 | 
            +
                # Removes the receiver node from its parent.  The reciever node becomes the new root for its subtree.
         | 
| 236 | 
            +
                #
         | 
| 237 | 
            +
                # If this is the root node, then does nothing.
         | 
| 238 | 
            +
                #
         | 
| 239 | 
            +
                # Returns self (the removed receiver node) if the operation is successful, and +nil+ otherwise.
         | 
| 202 240 | 
             
                def removeFromParent!
         | 
| 203 241 | 
             
                  @parent.remove!(self) unless isRoot?
         | 
| 204 242 | 
             
                end
         | 
| 205 243 |  | 
| 206 244 | 
             
                # Removes all children from the receiver node.
         | 
| 245 | 
            +
                #
         | 
| 246 | 
            +
                # Returns the receiver node.
         | 
| 207 247 | 
             
                def removeAll!
         | 
| 208 248 | 
             
                  for child in @children
         | 
| 209 249 | 
             
                    child.setAsRoot!
         | 
| @@ -213,35 +253,38 @@ module Tree | |
| 213 253 | 
             
                  self
         | 
| 214 254 | 
             
                end
         | 
| 215 255 |  | 
| 216 | 
            -
                # Returns +true+ if  | 
| 256 | 
            +
                # Returns +true+ if the receiver node has any associated content.
         | 
| 217 257 | 
             
                def hasContent?
         | 
| 218 258 | 
             
                  @content != nil
         | 
| 219 259 | 
             
                end
         | 
| 220 260 |  | 
| 221 | 
            -
                # Protected method which sets  | 
| 222 | 
            -
                 | 
| 261 | 
            +
                # Protected method which sets the receiver node as a root node.
         | 
| 262 | 
            +
                #
         | 
| 263 | 
            +
                # Returns +nil+.
         | 
| 264 | 
            +
                def setAsRoot!              # :nodoc:
         | 
| 223 265 | 
             
                  @parent = nil
         | 
| 224 266 | 
             
                end
         | 
| 225 267 |  | 
| 226 | 
            -
                # Returns +true+ if  | 
| 268 | 
            +
                # Returns +true+ if the receiver is a root node.  Note that
         | 
| 227 269 | 
             
                # orphaned children will also be reported as root nodes.
         | 
| 228 270 | 
             
                def isRoot?
         | 
| 229 271 | 
             
                  @parent == nil
         | 
| 230 272 | 
             
                end
         | 
| 231 273 |  | 
| 232 | 
            -
                # Returns +true+ if  | 
| 274 | 
            +
                # Returns +true+ if the receiver node has any immediate child nodes.
         | 
| 233 275 | 
             
                def hasChildren?
         | 
| 234 276 | 
             
                  @children.length != 0
         | 
| 235 277 | 
             
                end
         | 
| 236 278 |  | 
| 237 | 
            -
                # Returns +true+ if  | 
| 279 | 
            +
                # Returns +true+ if the receiver node is a 'leaf' - i.e., one without
         | 
| 238 280 | 
             
                # any children.
         | 
| 239 281 | 
             
                def isLeaf?
         | 
| 240 282 | 
             
                  !hasChildren?
         | 
| 241 283 | 
             
                end
         | 
| 242 284 |  | 
| 243 | 
            -
                # Returns an array of all the immediate children | 
| 244 | 
            -
                # | 
| 285 | 
            +
                # Returns an array of all the immediate children of the receiver node.
         | 
| 286 | 
            +
                #
         | 
| 287 | 
            +
                # If a block is given, yields each child node to the block traversing from left to right.
         | 
| 245 288 | 
             
                def children
         | 
| 246 289 | 
             
                  if block_given?
         | 
| 247 290 | 
             
                    @children.each {|child| yield child}
         | 
| @@ -250,34 +293,37 @@ module Tree | |
| 250 293 | 
             
                  end
         | 
| 251 294 | 
             
                end
         | 
| 252 295 |  | 
| 253 | 
            -
                # Returns the first child of  | 
| 254 | 
            -
                # | 
| 296 | 
            +
                # Returns the first child of the receiver node.
         | 
| 297 | 
            +
                #
         | 
| 298 | 
            +
                # Will return +nil+ if no children are present.
         | 
| 255 299 | 
             
                def firstChild
         | 
| 256 300 | 
             
                  children.first
         | 
| 257 301 | 
             
                end
         | 
| 258 302 |  | 
| 259 | 
            -
                # Returns the last child of  | 
| 260 | 
            -
                # | 
| 303 | 
            +
                # Returns the last child of the receiver node.
         | 
| 304 | 
            +
                #
         | 
| 305 | 
            +
                # Will return +nil+ if no children are present.
         | 
| 261 306 | 
             
                def lastChild
         | 
| 262 307 | 
             
                  children.last
         | 
| 263 308 | 
             
                end
         | 
| 264 309 |  | 
| 265 | 
            -
                #  | 
| 266 | 
            -
                #  | 
| 267 | 
            -
                # | 
| 268 | 
            -
                 | 
| 310 | 
            +
                # Traverses every node (including the receiver node) from the (sub)tree
         | 
| 311 | 
            +
                # by yielding the node to the specified block.
         | 
| 312 | 
            +
                #
         | 
| 313 | 
            +
                # The traversal is depth-first and from left to right in pre-ordered sequence.
         | 
| 314 | 
            +
                def each &block             # :yields: node
         | 
| 269 315 | 
             
                  yield self
         | 
| 270 316 | 
             
                  children { |child| child.each(&block) }
         | 
| 271 317 | 
             
                end
         | 
| 272 318 |  | 
| 273 | 
            -
                # Traverses the tree in a pre-ordered sequence. | 
| 319 | 
            +
                # Traverses the tree in a pre-ordered sequence.  This is equivalent to
         | 
| 274 320 | 
             
                # TreeNode#each
         | 
| 275 | 
            -
                def preordered_each &block
         | 
| 321 | 
            +
                def preordered_each &block  # :yields: node
         | 
| 276 322 | 
             
                  each(&block)
         | 
| 277 323 | 
             
                end
         | 
| 278 324 |  | 
| 279 | 
            -
                # Performs breadth first traversal of the tree starting at  | 
| 280 | 
            -
                # traversal  | 
| 325 | 
            +
                # Performs breadth first traversal of the tree starting at the receiver node. The
         | 
| 326 | 
            +
                # traversal at a given level is from left to right.
         | 
| 281 327 | 
             
                def breadth_each &block
         | 
| 282 328 | 
             
                  node_queue = [self]       # Create a queue with self as the initial entry
         | 
| 283 329 |  | 
| @@ -290,18 +336,21 @@ module Tree | |
| 290 336 | 
             
                  end
         | 
| 291 337 | 
             
                end
         | 
| 292 338 |  | 
| 293 | 
            -
                # Yields all leaf nodes from  | 
| 294 | 
            -
                # | 
| 295 | 
            -
                #  | 
| 339 | 
            +
                # Yields all leaf nodes from the receiver node to the specified block.
         | 
| 340 | 
            +
                #
         | 
| 341 | 
            +
                # May yield this node as well if this is a leaf node.
         | 
| 342 | 
            +
                # Leaf traversal is depth-first and left to right.
         | 
| 296 343 | 
             
                def each_leaf &block
         | 
| 297 344 | 
             
                  self.each { |node| yield(node) if node.isLeaf? }
         | 
| 298 345 | 
             
                end
         | 
| 299 346 |  | 
| 300 347 | 
             
                # Returns the requested node from the set of immediate children.
         | 
| 301 348 | 
             
                #
         | 
| 302 | 
            -
                # If the  | 
| 303 | 
            -
                # accessed (see Tree#children).  If the  | 
| 304 | 
            -
                # is assumed to be  | 
| 349 | 
            +
                # If the argument is _numeric_, then the in-sequence array of children is
         | 
| 350 | 
            +
                # accessed (see Tree#children).  If the argument is *NOT* _numeric_, then it
         | 
| 351 | 
            +
                # is assumed to be *name* of the child node to be returned.
         | 
| 352 | 
            +
                #
         | 
| 353 | 
            +
                # Raises an exception is the requested child node is not found.
         | 
| 305 354 | 
             
                def [](name_or_index)
         | 
| 306 355 | 
             
                  raise "Name_or_index needs to be provided" if name_or_index == nil
         | 
| 307 356 |  | 
| @@ -312,11 +361,11 @@ module Tree | |
| 312 361 | 
             
                  end
         | 
| 313 362 | 
             
                end
         | 
| 314 363 |  | 
| 315 | 
            -
                # Returns the total number of nodes in this tree, including  | 
| 364 | 
            +
                # Returns the total number of nodes in this (sub)tree, including the receiver node.
         | 
| 316 365 | 
             
                #
         | 
| 317 366 | 
             
                # Size of the tree is defined as:
         | 
| 318 367 | 
             
                #
         | 
| 319 | 
            -
                # Size::  | 
| 368 | 
            +
                # Size:: Total number nodes in the subtree including the receiver node.
         | 
| 320 369 | 
             
                def size
         | 
| 321 370 | 
             
                  @children.inject(1) {|sum, node| sum + node.size}
         | 
| 322 371 | 
             
                end
         | 
| @@ -344,105 +393,131 @@ module Tree | |
| 344 393 | 
             
                  children { |child| child.printTree(level + 1)}
         | 
| 345 394 | 
             
                end
         | 
| 346 395 |  | 
| 347 | 
            -
                # Returns  | 
| 396 | 
            +
                # Returns root node for the (sub)tree to which the receiver node belongs.
         | 
| 397 | 
            +
                #
         | 
| 398 | 
            +
                # Note that a root node's root is itself (*beware* of any loop construct that may become infinite!)
         | 
| 399 | 
            +
                #--
         | 
| 400 | 
            +
                # TODO: We should perhaps return nil as root's root.
         | 
| 401 | 
            +
                #++
         | 
| 348 402 | 
             
                def root
         | 
| 349 403 | 
             
                  root = self
         | 
| 350 404 | 
             
                  root = root.parent while !root.isRoot?
         | 
| 351 405 | 
             
                  root
         | 
| 352 406 | 
             
                end
         | 
| 353 407 |  | 
| 354 | 
            -
                # Returns the first sibling for  | 
| 408 | 
            +
                # Returns the first sibling for the receiver node. If this is the root node, returns
         | 
| 355 409 | 
             
                # itself.
         | 
| 410 | 
            +
                #
         | 
| 411 | 
            +
                # 'First' sibling is defined as follows:
         | 
| 412 | 
            +
                # First sibling:: The left-most child of the receiver's parent, which may be the receiver itself
         | 
| 413 | 
            +
                #--
         | 
| 414 | 
            +
                # TODO: Fix the inconsistency of returning root as its first sibling, and returning a
         | 
| 415 | 
            +
                #       a nil array for siblings for the node.
         | 
| 416 | 
            +
                #++
         | 
| 356 417 | 
             
                def firstSibling
         | 
| 357 | 
            -
                   | 
| 358 | 
            -
                    self
         | 
| 359 | 
            -
                  else
         | 
| 360 | 
            -
                    parent.children.first
         | 
| 361 | 
            -
                  end
         | 
| 418 | 
            +
                  isRoot? ? self : parent.children.first
         | 
| 362 419 | 
             
                end
         | 
| 363 420 |  | 
| 364 | 
            -
                # Returns true if  | 
| 421 | 
            +
                # Returns true if the receiver node is the first sibling.
         | 
| 365 422 | 
             
                def isFirstSibling?
         | 
| 366 423 | 
             
                  firstSibling == self
         | 
| 367 424 | 
             
                end
         | 
| 368 425 |  | 
| 369 | 
            -
                # Returns the last sibling for  | 
| 426 | 
            +
                # Returns the last sibling for the receiver node.  If this is the root node, returns
         | 
| 370 427 | 
             
                # itself.
         | 
| 428 | 
            +
                #
         | 
| 429 | 
            +
                # 'Last' sibling is defined as follows:
         | 
| 430 | 
            +
                # Last sibling:: The right-most child of the receiver's parent, which may be the receiver itself
         | 
| 431 | 
            +
                #--
         | 
| 432 | 
            +
                # TODO: Fix the inconsistency of returning root as its last sibling, and returning a
         | 
| 433 | 
            +
                #       a nil array for siblings for the node.
         | 
| 434 | 
            +
                #++
         | 
| 371 435 | 
             
                def lastSibling
         | 
| 372 | 
            -
                   | 
| 373 | 
            -
                    self
         | 
| 374 | 
            -
                  else
         | 
| 375 | 
            -
                    parent.children.last
         | 
| 376 | 
            -
                  end
         | 
| 436 | 
            +
                  isRoot? ? self : parent.children.last
         | 
| 377 437 | 
             
                end
         | 
| 378 438 |  | 
| 379 | 
            -
                # Returns true if  | 
| 439 | 
            +
                # Returns true if the receivere node is the last sibling.
         | 
| 380 440 | 
             
                def isLastSibling?
         | 
| 381 441 | 
             
                  lastSibling == self
         | 
| 382 442 | 
             
                end
         | 
| 383 443 |  | 
| 384 | 
            -
                # Returns an array of siblings for  | 
| 385 | 
            -
                # | 
| 386 | 
            -
                #  | 
| 444 | 
            +
                # Returns an array of siblings for the receiver node.  The receiver node is excluded.
         | 
| 445 | 
            +
                #
         | 
| 446 | 
            +
                # If a block is provided, yields each of the sibling nodes to the block.
         | 
| 447 | 
            +
                # The root always has +nil+ siblings.
         | 
| 448 | 
            +
                #--
         | 
| 449 | 
            +
                # TODO: Fix the inconsistency of returning root as its first/last sibling, and returning a
         | 
| 450 | 
            +
                #       a nil array for siblings for the node.
         | 
| 451 | 
            +
                #++
         | 
| 387 452 | 
             
                def siblings
         | 
| 388 453 | 
             
                  return nil if isRoot?
         | 
| 454 | 
            +
             | 
| 389 455 | 
             
                  if block_given?
         | 
| 390 456 | 
             
                    for sibling in parent.children
         | 
| 391 457 | 
             
                      yield sibling if sibling != self
         | 
| 392 458 | 
             
                    end
         | 
| 393 459 | 
             
                  else
         | 
| 394 460 | 
             
                    siblings = []
         | 
| 395 | 
            -
                    parent.children {| | 
| 461 | 
            +
                    parent.children {|my_sibling| siblings << my_sibling if my_sibling != self}
         | 
| 396 462 | 
             
                    siblings
         | 
| 397 463 | 
             
                  end
         | 
| 398 464 | 
             
                end
         | 
| 399 465 |  | 
| 400 | 
            -
                # Returns true if  | 
| 466 | 
            +
                # Returns true if the receiver node is the only child of its parent.
         | 
| 401 467 | 
             
                def isOnlyChild?
         | 
| 402 468 | 
             
                  parent.children.size == 1
         | 
| 403 469 | 
             
                end
         | 
| 404 470 |  | 
| 405 | 
            -
                # Returns the next sibling for  | 
| 406 | 
            -
                # node is  | 
| 471 | 
            +
                # Returns the next sibling for the receiver node.
         | 
| 472 | 
            +
                # The 'next' node is defined as the node to right of the receiver node.
         | 
| 473 | 
            +
                #
         | 
| 474 | 
            +
                # Will return +nil+ if no subsequent node is present.
         | 
| 407 475 | 
             
                def nextSibling
         | 
| 408 476 | 
             
                  if myidx = parent.children.index(self)
         | 
| 409 477 | 
             
                    parent.children.at(myidx + 1)
         | 
| 410 478 | 
             
                  end
         | 
| 411 479 | 
             
                end
         | 
| 412 480 |  | 
| 413 | 
            -
                # Returns the previous sibling for  | 
| 414 | 
            -
                #  | 
| 481 | 
            +
                # Returns the previous sibling for the receiver node.
         | 
| 482 | 
            +
                # The 'previous' node is defined as the node to left of the receiver node.
         | 
| 483 | 
            +
                #
         | 
| 484 | 
            +
                # Will return nil if no predecessor node is present.
         | 
| 415 485 | 
             
                def previousSibling
         | 
| 416 486 | 
             
                  if myidx = parent.children.index(self)
         | 
| 417 487 | 
             
                    parent.children.at(myidx - 1) if myidx > 0
         | 
| 418 488 | 
             
                  end
         | 
| 419 489 | 
             
                end
         | 
| 420 490 |  | 
| 421 | 
            -
                # Provides a comparision operation for the nodes. | 
| 422 | 
            -
                # | 
| 423 | 
            -
                # node  | 
| 491 | 
            +
                # Provides a comparision operation for the nodes.
         | 
| 492 | 
            +
                #
         | 
| 493 | 
            +
                # Comparision is based on the natural character-set ordering of the *node name*.
         | 
| 424 494 | 
             
                def <=>(other)
         | 
| 425 495 | 
             
                  return +1 if other == nil
         | 
| 426 496 | 
             
                  self.name <=> other.name
         | 
| 427 497 | 
             
                end
         | 
| 428 498 |  | 
| 429 | 
            -
                # Freezes all nodes in the tree
         | 
| 499 | 
            +
                # Freezes all nodes in the (sub)tree rooted at the receiver node.
         | 
| 430 500 | 
             
                def freezeTree!
         | 
| 431 501 | 
             
                  each {|node| node.freeze}
         | 
| 432 502 | 
             
                end
         | 
| 433 503 |  | 
| 434 | 
            -
                #  | 
| 504 | 
            +
                # Returns a marshal-dump represention of the (sub)tree rooted at the receiver node.
         | 
| 435 505 | 
             
                def marshal_dump
         | 
| 436 506 | 
             
                  self.collect { |node| node.createDumpRep }
         | 
| 437 507 | 
             
                end
         | 
| 438 508 |  | 
| 439 | 
            -
                # Creates a dump representation and returns the same as a hash.
         | 
| 440 | 
            -
                def createDumpRep
         | 
| 509 | 
            +
                # Creates a dump representation of the reciever node and returns the same as a hash.
         | 
| 510 | 
            +
                def createDumpRep           # :nodoc:
         | 
| 441 511 | 
             
                  { :name => @name, :parent => (isRoot? ? nil : @parent.name),  :content => Marshal.dump(@content)}
         | 
| 442 512 | 
             
                end
         | 
| 443 513 |  | 
| 444 | 
            -
                # Loads a marshalled dump of  | 
| 514 | 
            +
                # Loads a marshalled dump of a tree and returns the root node of the
         | 
| 445 515 | 
             
                # reconstructed tree. See the Marshal class for additional details.
         | 
| 516 | 
            +
                #
         | 
| 517 | 
            +
                #--
         | 
| 518 | 
            +
                # TODO: This method probably should be a class method.  It currently clobbers self
         | 
| 519 | 
            +
                #       and makes itself the root.
         | 
| 520 | 
            +
                #++
         | 
| 446 521 | 
             
                def marshal_load(dumped_tree_array)
         | 
| 447 522 | 
             
                  nodes = { }
         | 
| 448 523 | 
             
                  for node_hash in dumped_tree_array do
         | 
| @@ -458,37 +533,41 @@ module Tree | |
| 458 533 | 
             
                      initialize(name, content)
         | 
| 459 534 |  | 
| 460 535 | 
             
                      nodes[name] = self    # Add self to the list of nodes
         | 
| 461 | 
            -
             | 
| 536 | 
            +
                    end
         | 
| 462 537 | 
             
                  end
         | 
| 463 538 | 
             
                end
         | 
| 464 539 |  | 
| 465 | 
            -
                # Returns height of the (sub)tree from  | 
| 540 | 
            +
                # Returns height of the (sub)tree from the receiver node.  Height of a node is defined as:
         | 
| 541 | 
            +
                #
         | 
| 542 | 
            +
                # Height:: Length of the longest downward path to a leaf from the node.
         | 
| 466 543 | 
             
                #
         | 
| 467 | 
            -
                #  | 
| 468 | 
            -
                #  | 
| 544 | 
            +
                # - Height from a root node is height of the entire tree.
         | 
| 545 | 
            +
                # - The height of a leaf node is zero.
         | 
| 469 546 | 
             
                def nodeHeight
         | 
| 470 547 | 
             
                  return 0 if isLeaf?
         | 
| 471 548 | 
             
                  1 + @children.collect { |child| child.nodeHeight }.max
         | 
| 472 549 | 
             
                end
         | 
| 473 550 |  | 
| 474 | 
            -
                # Returns depth  | 
| 551 | 
            +
                # Returns depth of the receiver node in its tree.  Depth of a node is defined as:
         | 
| 475 552 | 
             
                #
         | 
| 476 553 | 
             
                # Depth:: Length of the node's path to its root.  Depth of a root node is zero.
         | 
| 477 554 | 
             
                #
         | 
| 478 | 
            -
                # Note that the deprecated method Tree::TreeNode#depth was incorrectly computing this value. | 
| 479 | 
            -
                # calls to the old method  | 
| 555 | 
            +
                # *Note* that the deprecated method Tree::TreeNode#depth was incorrectly computing this value.
         | 
| 556 | 
            +
                # Please replace all calls to the old method with Tree::TreeNode#nodeDepth instead.
         | 
| 480 557 | 
             
                def nodeDepth
         | 
| 481 558 | 
             
                  return 0 if isRoot?
         | 
| 482 559 | 
             
                  1 + parent.nodeDepth
         | 
| 483 560 | 
             
                end
         | 
| 484 561 |  | 
| 485 | 
            -
                # Returns depth of the tree from  | 
| 562 | 
            +
                # Returns depth of the tree from the receiver node. A single leaf node has a depth of 1.
         | 
| 563 | 
            +
                #
         | 
| 564 | 
            +
                # This method is *DEPRECATED* and may be removed in the subsequent releases.
         | 
| 565 | 
            +
                # Note that the value returned by this method is actually the:
         | 
| 486 566 | 
             
                #
         | 
| 487 | 
            -
                #  | 
| 488 | 
            -
                # returned by this method is actually the _height_ + 1 of the node, *not* the _depth_.
         | 
| 567 | 
            +
                # _height_ + 1 of the node, *NOT* the _depth_.
         | 
| 489 568 | 
             
                #
         | 
| 490 | 
            -
                # For correct and conventional behavior, please use Tree::TreeNode#nodeDepth and | 
| 491 | 
            -
                # instead.
         | 
| 569 | 
            +
                # For correct and conventional behavior, please use Tree::TreeNode#nodeDepth and
         | 
| 570 | 
            +
                # Tree::TreeNode#nodeHeight methods instead.
         | 
| 492 571 | 
             
                def depth
         | 
| 493 572 | 
             
                  begin
         | 
| 494 573 | 
             
                    require 'structured_warnings'   # To enable a nice way of deprecating of the depth method.
         | 
| @@ -498,17 +577,17 @@ module Tree | |
| 498 577 | 
             
                    warn 'Tree::TreeNode#depth() method is deprecated.  Please use nodeDepth() or nodeHeight() instead (bug # 22535)'
         | 
| 499 578 | 
             
                  end
         | 
| 500 579 |  | 
| 501 | 
            -
             | 
| 502 580 | 
             
                  return 1 if isLeaf?
         | 
| 503 581 | 
             
                  1 + @children.collect { |child| child.depth }.max
         | 
| 504 582 | 
             
                end
         | 
| 505 583 |  | 
| 506 | 
            -
                # Returns breadth of the tree at  | 
| 507 | 
            -
                #  | 
| 508 | 
            -
                # | 
| 584 | 
            +
                # Returns breadth of the tree at the receiver node's  level.
         | 
| 585 | 
            +
                # A single node without siblings has a breadth of 1.
         | 
| 586 | 
            +
                #
         | 
| 587 | 
            +
                # Breadth is defined to be:
         | 
| 588 | 
            +
                # Breadth:: Number of sibling nodes to this node + 1 (this node itself), i.e., the number of children the parent of this node has.
         | 
| 509 589 | 
             
                def breadth
         | 
| 510 | 
            -
                   | 
| 511 | 
            -
                  parent.children.size
         | 
| 590 | 
            +
                  isRoot? ? 1 : parent.children.size
         | 
| 512 591 | 
             
                end
         | 
| 513 592 |  | 
| 514 593 | 
             
                protected :parent=, :setAsRoot!, :createDumpRep
         | 
    
        data/lib/tree/binarytree.rb
    CHANGED
    
    | @@ -1,12 +1,11 @@ | |
| 1 | 
            -
            # binarytree.rb
         | 
| 1 | 
            +
            # binarytree.rb - This file is part of the RubyTree package.
         | 
| 2 2 | 
             
            #
         | 
| 3 | 
            -
            # $Revision | 
| 3 | 
            +
            # $Revision$ by $Author$ on $Date$
         | 
| 4 4 | 
             
            #
         | 
| 5 | 
            -
            # = binarytree.rb -  | 
| 5 | 
            +
            # = binarytree.rb - An implementation of the binary tree data structure.
         | 
| 6 6 | 
             
            #
         | 
| 7 | 
            -
            # Provides a  | 
| 8 | 
            -
            # store  | 
| 9 | 
            -
            # mixes in the Enumerable module.
         | 
| 7 | 
            +
            # Provides a binary tree data structure with ability to
         | 
| 8 | 
            +
            # store two node elements as children at each node in the tree.
         | 
| 10 9 | 
             
            #
         | 
| 11 10 | 
             
            # Author:: Anupam Sengupta (anupamsg@gmail.com)
         | 
| 12 11 | 
             
            #
         | 
| @@ -45,61 +44,67 @@ require 'tree' | |
| 45 44 |  | 
| 46 45 | 
             
            module Tree
         | 
| 47 46 |  | 
| 48 | 
            -
              # Provides a Binary tree implementation. This  | 
| 47 | 
            +
              # Provides a Binary tree implementation. This node allows only two child nodes (left and right child).  It also
         | 
| 49 48 | 
             
              # provides direct access to the left or right child, including assignment to the same.
         | 
| 49 | 
            +
              #
         | 
| 50 | 
            +
              # This inherits from the Tree::TreeNode class.
         | 
| 50 51 | 
             
              class BinaryTreeNode < TreeNode
         | 
| 51 52 |  | 
| 52 | 
            -
                # Adds the specified child node to the receiver node.  The child node's parent is set to be the receiver. | 
| 53 | 
            -
                # | 
| 54 | 
            -
                #  | 
| 53 | 
            +
                # Adds the specified child node to the receiver node.  The child node's parent is set to be the receiver.
         | 
| 54 | 
            +
                #
         | 
| 55 | 
            +
                # The child nodes are added in the order of addition, i.e., the first child added becomes the left node, and the
         | 
| 56 | 
            +
                # second child added will be the second node.
         | 
| 55 57 | 
             
                #
         | 
| 56 58 | 
             
                # If only one child is present, then this will be the left child.
         | 
| 59 | 
            +
                #
         | 
| 60 | 
            +
                # An exception is raised if two children are already present.
         | 
| 57 61 | 
             
                def add(child)
         | 
| 58 62 | 
             
                  raise "Already has two child nodes" if @children.size == 2
         | 
| 59 63 |  | 
| 60 64 | 
             
                  super(child)
         | 
| 61 65 | 
             
                end
         | 
| 62 66 |  | 
| 63 | 
            -
                # Returns the left child node. Note that left Child == first Child.
         | 
| 67 | 
            +
                # Returns the left child of the receiver node. Note that left Child == first Child.
         | 
| 64 68 | 
             
                def leftChild
         | 
| 65 69 | 
             
                  children.first
         | 
| 66 70 | 
             
                end
         | 
| 67 71 |  | 
| 68 | 
            -
                # Returns the right child node. Note that right child == last child unless there is only one child. | 
| 69 | 
            -
                # | 
| 72 | 
            +
                # Returns the right child of the receiver node. Note that right child == last child unless there is only one child.
         | 
| 73 | 
            +
                #
         | 
| 74 | 
            +
                # Returns +nil+ if the right child does not exist.
         | 
| 70 75 | 
             
                def rightChild
         | 
| 71 76 | 
             
                  children[1]
         | 
| 72 77 | 
             
                end
         | 
| 73 78 |  | 
| 74 | 
            -
                # Sets the left child. If a previous child existed, it is replaced.
         | 
| 79 | 
            +
                # Sets the left child of the receiver node. If a previous child existed, it is replaced.
         | 
| 75 80 | 
             
                def leftChild=(child)
         | 
| 76 81 | 
             
                  @children[0] = child
         | 
| 77 82 | 
             
                  @childrenHash[child.name] = child if child # Assign the name mapping
         | 
| 78 83 | 
             
                end
         | 
| 79 84 |  | 
| 80 | 
            -
                # Sets the right child. If a previous child existed, it is replaced.
         | 
| 85 | 
            +
                # Sets the right child of the receiver node. If a previous child existed, it is replaced.
         | 
| 81 86 | 
             
                def rightChild=(child)
         | 
| 82 87 | 
             
                  @children[1] = child
         | 
| 83 88 | 
             
                  @childrenHash[child.name] = child if child # Assign the name mapping
         | 
| 84 89 | 
             
                end
         | 
| 85 90 |  | 
| 86 | 
            -
                # Returns +true+ if  | 
| 91 | 
            +
                # Returns +true+ if the receiver node is the left child of its parent.  Always returns +false+ if it is a root node.
         | 
| 87 92 | 
             
                def isLeftChild?
         | 
| 88 | 
            -
                  return  | 
| 93 | 
            +
                  return false if isRoot?
         | 
| 89 94 | 
             
                  self == parent.leftChild
         | 
| 90 95 | 
             
                end
         | 
| 91 96 |  | 
| 92 | 
            -
                # Returns +true+ if  | 
| 97 | 
            +
                # Returns +true+ if the receiver node is the right child of its parent. Always returns +false+ if it is a root node.
         | 
| 93 98 | 
             
                def isRightChild?
         | 
| 94 | 
            -
                  return  | 
| 99 | 
            +
                  return false if isRoot?
         | 
| 95 100 | 
             
                  self == parent.rightChild
         | 
| 96 101 | 
             
                end
         | 
| 97 102 |  | 
| 98 | 
            -
                # Swaps the left and right child nodes with each other.
         | 
| 103 | 
            +
                # Swaps the left and right child nodes of the receiver node with each other.
         | 
| 99 104 | 
             
                def swap_children
         | 
| 100 | 
            -
                  tempChild | 
| 101 | 
            -
                  self.leftChild= rightChild
         | 
| 102 | 
            -
                  self.rightChild= tempChild
         | 
| 105 | 
            +
                  tempChild       = leftChild
         | 
| 106 | 
            +
                  self.leftChild  = rightChild
         | 
| 107 | 
            +
                  self.rightChild = tempChild
         | 
| 103 108 | 
             
                end
         | 
| 104 109 | 
             
              end
         | 
| 105 110 |  | 
    
        data/test/test_binarytree.rb
    CHANGED
    
    | @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            #!/usr/bin/env ruby
         | 
| 2 2 |  | 
| 3 | 
            -
            # test_binarytree.rb
         | 
| 3 | 
            +
            # test_binarytree.rb - This file is part of the RubyTree package.
         | 
| 4 4 | 
             
            #
         | 
| 5 | 
            -
            # $Revision | 
| 5 | 
            +
            # $Revision$ by $Author$ on $Date$
         | 
| 6 6 | 
             
            #
         | 
| 7 7 | 
             
            # Copyright (c) 2006, 2007, 2008, 2009, 2010 Anupam Sengupta
         | 
| 8 8 | 
             
            #
         | 
| @@ -38,7 +38,7 @@ require 'test/unit' | |
| 38 38 | 
             
            require 'tree/binarytree'
         | 
| 39 39 |  | 
| 40 40 | 
             
            module TestTree
         | 
| 41 | 
            -
              # Test class for the  | 
| 41 | 
            +
              # Test class for the binary tree node.
         | 
| 42 42 | 
             
              class TestBinaryTreeNode < Test::Unit::TestCase
         | 
| 43 43 |  | 
| 44 44 | 
             
                def setup
         | 
    
        data/test/test_tree.rb
    CHANGED
    
    | @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            #!/usr/bin/env ruby
         | 
| 2 2 |  | 
| 3 | 
            -
            # testtree.rb
         | 
| 3 | 
            +
            # testtree.rb - This file is part of the RubyTree package.
         | 
| 4 4 | 
             
            #
         | 
| 5 | 
            -
            # $Revision | 
| 5 | 
            +
            # $Revision$ by $Author$ on $Date$
         | 
| 6 6 | 
             
            #
         | 
| 7 7 | 
             
            # Copyright (c) 2006, 2007, 2008, 2009, 2010 Anupam Sengupta
         | 
| 8 8 | 
             
            #
         | 
| @@ -41,7 +41,7 @@ module TestTree | |
| 41 41 | 
             
              # Test class for the Tree node.
         | 
| 42 42 | 
             
              class TestTreeNode < Test::Unit::TestCase
         | 
| 43 43 |  | 
| 44 | 
            -
                Person = Struct::new(:First, :last)
         | 
| 44 | 
            +
                Person = Struct::new(:First, :last) # A simple structure to use as the content for the nodes.
         | 
| 45 45 |  | 
| 46 46 | 
             
                def setup
         | 
| 47 47 | 
             
                  @root = Tree::TreeNode.new("ROOT", "Root Node")
         | 
| @@ -83,16 +83,16 @@ module TestTree | |
| 83 83 |  | 
| 84 84 | 
             
                # This test is for the root alone - without any children being linked
         | 
| 85 85 | 
             
                def test_root_setup
         | 
| 86 | 
            -
                  assert_not_nil(@root, "Root cannot be nil")
         | 
| 87 | 
            -
                  assert_nil(@root.parent, "Parent of root node should be nil")
         | 
| 88 | 
            -
                  assert_not_nil(@root.name, "Name should not be nil")
         | 
| 89 | 
            -
                  assert_equal("ROOT", @root.name, "Name should be 'ROOT'")
         | 
| 90 | 
            -
                  assert_equal("Root Node", @root.content, "Content should be 'Root Node'")
         | 
| 91 | 
            -
                  assert(@root.isRoot | 
| 92 | 
            -
                  assert(!@root.hasChildren | 
| 93 | 
            -
                  assert(@root.hasContent | 
| 94 | 
            -
                  assert_equal(1, @root.size, "Number of nodes should be one")
         | 
| 95 | 
            -
                  assert_nil(@root.siblings, "This root does not have any children")
         | 
| 86 | 
            +
                  assert_not_nil(@root       , "Root cannot be nil")
         | 
| 87 | 
            +
                  assert_nil(@root.parent    , "Parent of root node should be nil")
         | 
| 88 | 
            +
                  assert_not_nil(@root.name  , "Name should not be nil")
         | 
| 89 | 
            +
                  assert_equal("ROOT"        , @root.name, "Name should be 'ROOT'")
         | 
| 90 | 
            +
                  assert_equal("Root Node"   , @root.content, "Content should be 'Root Node'")
         | 
| 91 | 
            +
                  assert(@root.isRoot?       , "Should identify as root")
         | 
| 92 | 
            +
                  assert(!@root.hasChildren? , "Cannot have any children")
         | 
| 93 | 
            +
                  assert(@root.hasContent?   , "This root should have content")
         | 
| 94 | 
            +
                  assert_equal(1             , @root.size, "Number of nodes should be one")
         | 
| 95 | 
            +
                  assert_nil(@root.siblings  , "This root does not have any children")
         | 
| 96 96 |  | 
| 97 97 | 
             
                  assert_equal(0, @root.nodeHeight, "Root's height before adding any children is 0")
         | 
| 98 98 | 
             
                  assert_raise(RuntimeError) { Tree::TreeNode.new(nil) }
         | 
| @@ -102,16 +102,16 @@ module TestTree | |
| 102 102 | 
             
                def test_root
         | 
| 103 103 | 
             
                  loadChildren
         | 
| 104 104 |  | 
| 105 | 
            -
                  assert_same(@root, @root.root, "Root's root is self")
         | 
| 106 | 
            -
                  assert_same(@root, @child1.root, "Root should be ROOT")
         | 
| 107 | 
            -
                  assert_same(@root, @child4.root, "Root should be ROOT")
         | 
| 108 | 
            -
                  assert_equal(2, @root.nodeHeight, "Root's height after adding the children should be 2")
         | 
| 105 | 
            +
                  assert_same(@root , @root.root, "Root's root is self")
         | 
| 106 | 
            +
                  assert_same(@root , @child1.root, "Root should be ROOT")
         | 
| 107 | 
            +
                  assert_same(@root , @child4.root, "Root should be ROOT")
         | 
| 108 | 
            +
                  assert_equal(2    , @root.nodeHeight, "Root's height after adding the children should be 2")
         | 
| 109 109 | 
             
                end
         | 
| 110 110 |  | 
| 111 111 | 
             
                def test_hasContent_eh
         | 
| 112 112 | 
             
                  aNode = Tree::TreeNode.new("A Node")
         | 
| 113 | 
            -
                  assert_nil(aNode.content, "The node should not have content")
         | 
| 114 | 
            -
                  assert(!aNode.hasContent | 
| 113 | 
            +
                  assert_nil(aNode.content  , "The node should not have content")
         | 
| 114 | 
            +
                  assert(!aNode.hasContent? , "The node should not have content")
         | 
| 115 115 |  | 
| 116 116 | 
             
                  aNode.content = "Something"
         | 
| 117 117 | 
             
                  assert_not_nil(aNode.content, "The node should now have content")
         | 
| @@ -496,8 +496,11 @@ module TestTree | |
| 496 496 | 
             
                  @root.content = "ABC"
         | 
| 497 497 | 
             
                  assert_equal("ABC", @root.content, "Content should be 'ABC'")
         | 
| 498 498 | 
             
                  @root.freezeTree!
         | 
| 499 | 
            -
                   | 
| 500 | 
            -
                   | 
| 499 | 
            +
                  # Note: The error raised here depends on the Ruby version.
         | 
| 500 | 
            +
                  # For Ruby > 1.9, RuntimeError is raised
         | 
| 501 | 
            +
                  # For Ruby ~ 1.8, TypeError is raised
         | 
| 502 | 
            +
                  assert_raise(RuntimeError, TypeError) {@root.content = "123"}
         | 
| 503 | 
            +
                  assert_raise(RuntimeError, TypeError) {@root[0].content = "123"}
         | 
| 501 504 | 
             
                end
         | 
| 502 505 |  | 
| 503 506 | 
             
                # Test whether the content is accesible
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: rubytree
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
              version: 0.6. | 
| 4 | 
            +
              version: 0.6.2
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors: 
         | 
| 7 7 | 
             
            - Anupam Sengupta
         | 
| @@ -9,9 +9,29 @@ autorequire: | |
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 11 |  | 
| 12 | 
            -
            date: 2010-01- | 
| 12 | 
            +
            date: 2010-01-30 00:00:00 +05:30
         | 
| 13 13 | 
             
            default_executable: 
         | 
| 14 14 | 
             
            dependencies: 
         | 
| 15 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 16 | 
            +
              name: rubyforge
         | 
| 17 | 
            +
              type: :development
         | 
| 18 | 
            +
              version_requirement: 
         | 
| 19 | 
            +
              version_requirements: !ruby/object:Gem::Requirement 
         | 
| 20 | 
            +
                requirements: 
         | 
| 21 | 
            +
                - - ">="
         | 
| 22 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 23 | 
            +
                    version: 2.0.3
         | 
| 24 | 
            +
                version: 
         | 
| 25 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 26 | 
            +
              name: gemcutter
         | 
| 27 | 
            +
              type: :development
         | 
| 28 | 
            +
              version_requirement: 
         | 
| 29 | 
            +
              version_requirements: !ruby/object:Gem::Requirement 
         | 
| 30 | 
            +
                requirements: 
         | 
| 31 | 
            +
                - - ">="
         | 
| 32 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 33 | 
            +
                    version: 0.3.0
         | 
| 34 | 
            +
                version: 
         | 
| 15 35 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| 16 36 | 
             
              name: hoe
         | 
| 17 37 | 
             
              type: :development
         | 
| @@ -20,13 +40,14 @@ dependencies: | |
| 20 40 | 
             
                requirements: 
         | 
| 21 41 | 
             
                - - ">="
         | 
| 22 42 | 
             
                  - !ruby/object:Gem::Version 
         | 
| 23 | 
            -
                    version: 2. | 
| 43 | 
            +
                    version: 2.5.0
         | 
| 24 44 | 
             
                version: 
         | 
| 25 45 | 
             
            description: |-
         | 
| 26 | 
            -
              RubyTree is a Ruby implementation of the generic  | 
| 27 | 
            -
               | 
| 28 | 
            -
              the tree are the primary  | 
| 29 | 
            -
               | 
| 46 | 
            +
              RubyTree is a Ruby implementation of the generic tree data structure.  It provides a node-based model to store keyed
         | 
| 47 | 
            +
              node-elements in the tree and simple APIs to access, modify and traverse the structure.  RubyTree is node-centric, where
         | 
| 48 | 
            +
              individual nodes on the tree are the primary compositional and structural elements.
         | 
| 49 | 
            +
              
         | 
| 50 | 
            +
              This implementation also mixes in the Enumerable module to allow standard access to the tree as a collection.
         | 
| 30 51 | 
             
            email: 
         | 
| 31 52 | 
             
            - anupamsg@gmail.com
         | 
| 32 53 | 
             
            executables: []
         | 
| @@ -56,7 +77,18 @@ has_rdoc: true | |
| 56 77 | 
             
            homepage: http://rubytree.rubyforge.org
         | 
| 57 78 | 
             
            licenses: []
         | 
| 58 79 |  | 
| 59 | 
            -
            post_install_message: 
         | 
| 80 | 
            +
            post_install_message: |
         | 
| 81 | 
            +
              ========================================================================
         | 
| 82 | 
            +
              
         | 
| 83 | 
            +
               Thank you for installing Rubytree.
         | 
| 84 | 
            +
              
         | 
| 85 | 
            +
               Please note that a few APIs have been deprecated since Version 0.6.1
         | 
| 86 | 
            +
              
         | 
| 87 | 
            +
               Specifically, the 'Tree::TreeNode#depth' method is now deprecated, and
         | 
| 88 | 
            +
               a new nodeDepth() method has been introduced.
         | 
| 89 | 
            +
              
         | 
| 90 | 
            +
              ========================================================================
         | 
| 91 | 
            +
             | 
| 60 92 | 
             
            rdoc_options: 
         | 
| 61 93 | 
             
            - --main
         | 
| 62 94 | 
             
            - README
         | 
| @@ -81,7 +113,7 @@ rubyforge_project: rubytree | |
| 81 113 | 
             
            rubygems_version: 1.3.5
         | 
| 82 114 | 
             
            signing_key: 
         | 
| 83 115 | 
             
            specification_version: 3
         | 
| 84 | 
            -
            summary: RubyTree is a Ruby implementation of the generic  | 
| 116 | 
            +
            summary: RubyTree is a Ruby implementation of the generic tree data structure
         | 
| 85 117 | 
             
            test_files: 
         | 
| 86 118 | 
             
            - test/test_binarytree.rb
         | 
| 87 119 | 
             
            - test/test_tree.rb
         |