Class: Tree::TreeNode

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/tree.rb

Overview

The Tree node class implementation. Mixes in the Enumerable module.

Example

require ‘tree’

myTreeRoot = Tree::TreeNode.new(“ROOT”, “Root Content”)

myTreeRoot << Tree::TreeNode.new(“CHILD1”, “Child1 Content”) << Tree::TreeNode.new(“GRANDCHILD1”, “GrandChild1 Content”)

myTreeRoot << Tree::TreeNode.new(“CHILD2”, “Child2 Content”)

myTreeRoot.printTree

child1 = myTreeRoot

grandChild1 = myTreeRoot[“GRANDCHILD1”]

siblingsOfChild1Array = child1.siblings

immediateChildrenArray = myTreeRoot.children

# Process all nodes

myTreeRoot.each { |node| node.content.reverse }

myTreeRoot.remove!(child1) # Remove the child

Constant Summary collapse

@@fieldSep =
'|'
@@recordSep =
"\n"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, content = nil) ⇒ TreeNode

Constructor which expects the name of the node

name of the node is expected to be unique across the tree.

The content can be of any type, and is defaulted to nil.



55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/tree.rb', line 55

def initialize(name, content = nil)
        
        raise "Node name HAS to be provided" if name == nil
        
        @name = name
        @content = content

        self.setAsRoot!

        @childrenHash = Hash.new
        @children = []
end

Instance Attribute Details

#contentObject

Returns the value of attribute content.



43
44
45
# File 'lib/tree.rb', line 43

def content
  @content
end

#nameObject (readonly)

Returns the value of attribute name.



43
44
45
# File 'lib/tree.rb', line 43

def name
  @name
end

#parentObject

Returns the value of attribute parent.



43
44
45
# File 'lib/tree.rb', line 43

def parent
  @parent
end

Class Method Details

._load(str) ⇒ Object



270
271
272
# File 'lib/tree.rb', line 270

def TreeNode._load(str)
    loadDumpRep(str)
end

Instance Method Details

#<<(child) ⇒ Object

Convenience synonym for Tree#add method. This method allows a convenient method to add children hierarchies in the tree. E.g. root << child << grand_child



87
88
89
# File 'lib/tree.rb', line 87

def <<(child)
    add(child)
end

#<=>(other) ⇒ Object

Provides a comparision operation for the nodes. Comparision is based on the natural character-set ordering for the node names.



230
231
232
233
# File 'lib/tree.rb', line 230

def <=>(other)
    return +1 if other == nil
    self.name <=> other.name
end

#[](key) ⇒ Object

Returns the requested node from the set of immediate children.

If the key is numeric, then the in-sequence array of children is accessed (see Tree#children). If the key is not numeric, then it is assumed to be the name of the child node to be returned.



177
178
179
180
181
182
183
184
185
# File 'lib/tree.rb', line 177

def [](key)
    raise "Key needs to be provided" if key == nil
    
    if key.kind_of?(Integer)
        @children[key]
    else
        @childrenHash[key]
    end
end

#_dump(depth) ⇒ Object



247
248
249
250
251
# File 'lib/tree.rb', line 247

def _dump(depth)
    strRep = String.new
    each {|node| strRep << node.createDumpRep}
    strRep
end

#add(child) ⇒ Object

Adds the specified child node to the receiver node. The child node’s parent is set to be the receiver. The child is added as the last child in the current list of children for the receiver node.



95
96
97
98
99
100
101
102
103
# File 'lib/tree.rb', line 95

def add(child)
    raise "Child already added" if @childrenHash.has_key?(child.name)

    @childrenHash[child.name]  = child
    @children << child
    child.parent = self
    return child

end

#childrenObject

Returns an array of all the immediate children. If a block is given, yields each child node to the block.



155
156
157
158
159
160
161
# File 'lib/tree.rb', line 155

def children
    if block_given?
        @children.each {|child| yield child}
    else
        @children
    end
end

#createDumpRepObject

Creates a dump representation



241
242
243
244
245
# File 'lib/tree.rb', line 241

def createDumpRep
    strRep = String.new
    strRep << @name << @@fieldSep << (isRoot? ? @name : @parent.name)
    strRep << @@fieldSep << Marshal.dump(@content) << @@recordSep
end

#each {|_self| ... } ⇒ Object

Returns every node (including the receiver node) from the tree to the specified block.

Yields:

  • (_self)

Yield Parameters:



165
166
167
168
# File 'lib/tree.rb', line 165

def each &block
    yield self
    children { |child| child.each(&block) }
end

#freezeTree!Object

Freezes all nodes in the tree



236
237
238
# File 'lib/tree.rb', line 236

def freezeTree!
    each {|node| node.freeze}
end

#hasChildren?Boolean

Indicates whether this node has any immediate child nodes.

Returns:

  • (Boolean)


149
150
151
# File 'lib/tree.rb', line 149

def hasChildren?
    @children.length != 0
end

#hasContent?Boolean

Indicates whether this node has any associated content.

Returns:

  • (Boolean)


133
134
135
# File 'lib/tree.rb', line 133

def hasContent?
    @content != nil
end

#isRoot?Boolean

Indicates whether this node is a root node. Note that orphaned children will also be reported as root nodes.

Returns:

  • (Boolean)


144
145
146
# File 'lib/tree.rb', line 144

def isRoot?
    @parent == nil
end

#lengthObject

Convenience synonym for Tree#size



194
195
196
# File 'lib/tree.rb', line 194

def length
    size()
end

#printTree(tab = 0) ⇒ Object

Pretty prints the tree starting with the receiver node.



199
200
201
202
# File 'lib/tree.rb', line 199

def printTree(tab = 0)
    puts((' ' * tab) + self.to_s)
    children {|child| child.printTree(tab + 4)}
end

#remove!(child) ⇒ Object

Removes the specified child node from the receiver node. The removed children nodes are orphaned but available if an alternate reference exists. Returns the child node.



109
110
111
112
113
114
# File 'lib/tree.rb', line 109

def remove!(child)
    @childrenHash.delete(child.name)
    @children.delete(child)
    child.setAsRoot! unless child == nil
    return child
end

#removeAll!Object

Removes all children from the receiver node.



123
124
125
126
127
128
129
130
# File 'lib/tree.rb', line 123

def removeAll!
    for child in @children
        child.setAsRoot!
    end
    @childrenHash.clear
    @children.clear
    self
end

#removeFromParent!Object

Removes this node from its parent. If this is the root node, then does nothing.



118
119
120
# File 'lib/tree.rb', line 118

def removeFromParent!
    @parent.remove!(self) unless isRoot?
end

#rootObject

Returns the root for this node.



205
206
207
208
209
# File 'lib/tree.rb', line 205

def root
    root = self
    root = root.parent while !root.isRoot?
    root
end

#siblingsObject

Returns an array of siblings for this node. If a block is provided, yeilds each of the sibling nodes to the block.



214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/tree.rb', line 214

def siblings
    if block_given?
        return nil if isRoot?
        for sibling in parent.children
		    yield sibling if sibling != self
        end
    else
        siblings = []
        parent.children {|sibling| siblings << sibling if sibling != self}
        siblings
    end
end

#sizeObject

Returns the total number of nodes in this tree, rooted at the receiver node.



189
190
191
# File 'lib/tree.rb', line 189

def size
    @children.inject(1) {|sum, node| sum + node.size}
end

#to_sObject

Print the string representation of this node.



69
70
71
72
73
74
75
# File 'lib/tree.rb', line 69

def to_s
        s = size()
        "Node ID: #{@name} Content: #{@content} Parent: " +
                (isRoot?()  ? "ROOT" : "#{@parent.name}") +
                " Children: #{@children.length}" +
                " Total Nodes: #{s}"
end