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:



121
122
123
124
125
# File 'lib/ole/support.rb', line 121

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.



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

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:



101
102
103
104
105
106
107
108
# File 'lib/ole/support.rb', line 101

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


137
138
139
# File 'lib/ole/support.rb', line 137

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

#to_tree(io = '', &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.



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/ole/support.rb', line 146

def to_tree io='', &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