Module: RecursivelyEnumerable

Included in:
Ole::Storage::Dirent
Defined in:
lib/ole/support.rb

Overview

Include this module into a class that defines #each_child. It should maybe use #each instead, but its easier to be more specific, and use an alias.

I don’t want to force the class to cache children (eg where children are loaded on request in pst), because that forces the whole tree to be loaded. So, the methods should only call #each_child once, and breadth first iteration holds its own copy of the children around.

Main methods are #recursive, and #to_tree

Instance Method Summary collapse

Instance Method Details

#each_recursive(mode = :depth_first) {|_self| ... } ⇒ Object

Yields:

  • (_self)

Yield Parameters:



113
114
115
116
117
# File 'lib/ole/support.rb', line 113

def each_recursive mode=:depth_first, &block
  # we always actually yield ourself (the tree root) before recursing
  yield self
  send "each_recursive_#{mode}", &block
end

#each_recursive_breadth_first(&block) ⇒ Object

don’t think this is actually a proper breadth first recursion. only first level is breadth first.



104
105
106
107
108
109
110
111
# File 'lib/ole/support.rb', line 104

def each_recursive_breadth_first(&block)
  children = []
  each_child do |child|
    children << child if child.respond_to? :each_recursive_breadth_first
    yield child
  end
  children.each { |child| child.each_recursive_breadth_first(&block) }
end

#each_recursive_depth_first(&block) ⇒ Object

:nodoc:



93
94
95
96
97
98
99
100
# File 'lib/ole/support.rb', line 93

def each_recursive_depth_first(&block)
  each_child do |child|
    yield child
    if child.respond_to? :each_recursive_depth_first
      child.each_recursive_depth_first(&block)
    end
  end
end

#recursive(mode = :depth_first) ⇒ Object

the idea of this function, is to allow use of regular Enumerable methods in a recursive fashion. eg:

# just looks at top level children
root.find { |child| child.some_condition? }
# recurse into all children getting non-folders, breadth first
root.recursive(:breadth_first).select { |child| !child.folder? }
# just get everything
items = root.recursive.to_a


129
130
131
# File 'lib/ole/support.rb', line 129

def recursive mode=:depth_first
  to_enum(:each_recursive, mode)
end

#to_tree(io = ''.dup, &inspect) ⇒ Object

streams a “tree” form of the recursively enumerable structure to io, or return a string form instead if io is not specified.

mostly a debugging aid. can specify a different block which will be called to provide the string form for each node.



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/ole/support.rb', line 138

def to_tree io=''.dup, &inspect
  inspect ||= :inspect.to_proc
  io << "- #{inspect[self]}\n"
  recurse = proc do |node, prefix|
    child = nil
    node.each_child do |next_child|
      if child
        io << "#{prefix}|- #{inspect[child]}\n"
        recurse.call child, prefix + '|  '
      end
      child = next_child
    end if node.respond_to?(:each_child)
    if child
      io << "#{prefix}\\- #{inspect[child]}\n"
      recurse.call child, prefix + '   '
    end
  end
  recurse.call self, '  '
  io
end