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:



117
118
119
120
121
# File 'lib/ole/support.rb', line 117

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.



108
109
110
111
112
113
114
115
# File 'lib/ole/support.rb', line 108

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:



97
98
99
100
101
102
103
104
# File 'lib/ole/support.rb', line 97

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


133
134
135
# File 'lib/ole/support.rb', line 133

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.



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/ole/support.rb', line 142

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