module SimpleTree

To use this interface, drop it in your current class with include. You must then simply implement the parent and children methods.

* +parent+ returns the parent node of the current node or else nil if it's a root
* +children+ returns an +Array+ of all children of this node or an empty +Array+ if it is a leaf node

Public Instance Methods

ancestors() click to toggle source

Return an array containing every ancestor of the current node.

# File lib/filetree/simple_tree.rb, line 110
def ancestors
  d = Array.new
  current = self.parent()
  d << current

  until d.include?(current.parent)
    current = current.parent
    d << current
  end

  d.flatten
end
children() click to toggle source
# File lib/filetree/simple_tree.rb, line 22
def children() raise "children must be overridden"; end
descendants() click to toggle source

Return an array containing every descendant of the current node.

# File lib/filetree/simple_tree.rb, line 126
def descendants
  d = Array.new

  children.each do |child|
    d << child
    d << child.descendants
  end

  d.flatten
end
family() click to toggle source

Return every node descending from this node’s parent (except this node). This include all of the node’s descendants.

# File lib/filetree/simple_tree.rb, line 96
def family
  if parent
    fam = [parent] + parent.descendants
  else
    fam = descendants
  end

  fam.delete(self)
  fam
end
grandparent() click to toggle source

Return the grandparent of this node.

# File lib/filetree/simple_tree.rb, line 141
def grandparent
  parent.parent if parent     # returns nil by default if no parent
end
has_children?() click to toggle source

Determine whether the node has children.

# File lib/filetree/simple_tree.rb, line 60
def has_children?
  not is_leaf?
end
has_parent?() click to toggle source

Determine whether the node has a parent.

# File lib/filetree/simple_tree.rb, line 52
def has_parent?
  not is_root?
end
height() click to toggle source

Return the height of this subtree. A single node has height 1.

# File lib/filetree/simple_tree.rb, line 68
def height
  heights = children.map {|child| child.height}
  return 1 if heights.size == 0
  return heights.max + 1
end
is_leaf?() click to toggle source

Return whether this node is a leaf node in the hierarchy.

# File lib/filetree/simple_tree.rb, line 28
def is_leaf?
  if children.size == 0
    true
  else
    false
  end
end
is_root?() click to toggle source

Determine whether this is the root node in the hierarchy.

# File lib/filetree/simple_tree.rb, line 40
def is_root?
  if parent
    false
  else
    true
  end
end
leaves() click to toggle source

Return all the leaf nodes having the current node as an ancestor.

# File lib/filetree/simple_tree.rb, line 149
def leaves
  outp = Array.new
  children.each do |child|
    if child.is_leaf?
      outp << child
    else
      outp << child.leaves
    end
  end

  outp.flatten
end
parent() click to toggle source
# File lib/filetree/simple_tree.rb, line 21
def parent() raise "parent must be overridden"; end
siblings() click to toggle source

Return an array containing the siblings of the current node.

# File lib/filetree/simple_tree.rb, line 78
def siblings
  # handle case where this is the root node
  return Array.new unless parent

  sibs = Array.new
  parent.children.each do |child|
    next if child.id == self.id
    sibs << child
  end

  sibs
end
tree_rep(depth=0) click to toggle source

Helper method for to_s, returns a tree representation of the subtree rooted at this node. This assumes some sort of identifier is specified for the object being called (self.name, self.identifier, etc)

# File lib/filetree/simple_tree.rb, line 168
def tree_rep(depth=0)
  if self.name
    ident = self.name
  elsif self.identifier
    ident = self.identifier
  else
    ident = self.object_id
  end
  if depth > 0
    outp = " #{(["    "] * (depth - 1)).join("|")}\\- #{ident}\n"
  else
    outp = "#{ident}\n"
  end
  children.each do |child|
    outp += child.tree_rep(depth + 1)
  end
  outp
end