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