Module: Sanction::Tree

Included in:
Node
Defined in:
lib/sanction/tree.rb

Instance Method Summary collapse

Instance Method Details

#ancestorsObject

Get all of the ancestors for this node.



53
54
55
56
57
58
59
60
# File 'lib/sanction/tree.rb', line 53

def ancestors
  ancestors = []
  if parent
    ancestors << parent
    parent.ancestors.each {|ancestor| ancestors << ancestor }
  end
  ancestors
end

#childrenObject

Get the children of this node.



29
30
31
# File 'lib/sanction/tree.rb', line 29

def children
  @children ||= []
end

#depthObject

An integer representation of how deep in the tree this node is. The root node has a depth of 1, its children have a depth of 2, etc.



76
77
78
# File 'lib/sanction/tree.rb', line 76

def depth
  ancestors.size + 1
end

#descendantsObject

Get all of the descendants of this node. All of its children, and its childrens’ children, and its childrens’ childrens’ children…



64
65
66
67
68
69
70
71
72
# File 'lib/sanction/tree.rb', line 64

def descendants
  descendants = []
  if !children.empty?
    (descendants << children).flatten!
    children.each {|descendant| descendants << descendant.descendants }
    descendants.flatten!   
  end
  descendants
end

#graft(node) ⇒ Object

Append a node to this node’s children, and return the node.



108
109
110
111
112
# File 'lib/sanction/tree.rb', line 108

def graft(node)
  node.instance_variable_set(:@parent, self)
  children << node
  node
end

#has_children?Boolean

Does this node have children? Is it not a leaf node?

Returns:

  • (Boolean)


48
49
50
# File 'lib/sanction/tree.rb', line 48

def has_children?
  !leaf?
end

#heightObject

From Wikipedia: The height of a node is the length of the longest downward path to a leaf from that node. In other words, the length of this node to its furthest descendant.



83
84
85
86
87
88
89
# File 'lib/sanction/tree.rb', line 83

def height
  if !leaf?
    descendants.collect {|child| child.depth }.uniq.size + 1
  else
    1
  end
end

#leaf?Boolean

Is this node a leaf node? Is this node childless?

Returns:

  • (Boolean)


15
16
17
# File 'lib/sanction/tree.rb', line 15

def leaf?
  children.nil? || children.empty?
end

#only_child?Boolean

Is this node the only child of its parent. Does it have any siblings?

Returns:

  • (Boolean)


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

def only_child?
  if parent
    siblings.empty?
  end
end

#parentObject

This node’s parent.



5
6
7
# File 'lib/sanction/tree.rb', line 5

def parent
  @parent
end

#pruneObject

Abandon all of this node’s children.



101
102
103
104
105
# File 'lib/sanction/tree.rb', line 101

def prune
  if children
    children.each {|child| child.unlink }
  end
end

#rootObject

Get the root node in this tree.



20
21
22
23
24
25
26
# File 'lib/sanction/tree.rb', line 20

def root
  if root?
    self
  else
    parent.root
  end
end

#root?Boolean

Is this node the root of the tree?

Returns:

  • (Boolean)


10
11
12
# File 'lib/sanction/tree.rb', line 10

def root?
  parent.nil?
end

#siblingsObject

Get the siblings of this node. The other children belonging to this node’s parent.



34
35
36
37
38
# File 'lib/sanction/tree.rb', line 34

def siblings
  if parent
    parent.children.reject {|child| child == self }
  end
end

Orphan this node. Remove it from its parent node.



92
93
94
95
96
97
98
# File 'lib/sanction/tree.rb', line 92

def unlink
  if parent
    parent.children.delete(self)
    self.instance_variable_set(:@parent, nil)
    return self
  end
end

#walk(&block) ⇒ Object

Recursively yield every node in the tree.



115
116
117
118
119
120
# File 'lib/sanction/tree.rb', line 115

def walk(&block)
  if block_given?
    yield self
    children.each {|child| child.walk(&block) }
  end
end