Module: Filigree::Visitable

Defined in:
lib/filigree/visitor.rb

Overview

This module provides a default implementation of three common traversal patterns: pre-order, post-order, and in-order (level-order). The including class must implement the ‘children` function.

Instance Method Summary collapse

Instance Method Details

#visit(visitor, method = :preorder) ⇒ Boolean

Visit this object with the provided visitor in pre-, post-, or in-order traversal.

Parameters:

  • visitor (Visitor)

    Visitor to call

  • method (:preorder, :inorder, :postorder, :downup) (defaults to: :preorder)

    How to visit

Returns:

  • (Boolean)

    If a pattern matched or not



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'lib/filigree/visitor.rb', line 237

def visit(visitor, method = :preorder)
	case method
	when :preorder
		res = (visitor.visit(self) != MatchError)
		children.flatten.compact.inject(false) { |mod, child| child.visit(visitor, :preorder) || mod } || res

	when :inorder
		mod   = false
		nodes = [self]

		# Not all Ruby implementations support modifying arrays while
		# you are iterating over them.
		while node = nodes.shift
			nodes += node.children.flatten.compact
			mod = visitor.visit(node) || mod
		end

		mod

	when :postorder
		res = children.flatten.compact.inject(false) { |mod, child| child.visit(visitor, :postorder) || mod }
		(visitor.visit(self) != MatchError) || res

	when :downup
		res = (visitor.visit(self) != MatchError)
		res = children.flatten.compact.inject(false) { |mod, child| child.visit(visitor, :downup) || mod } || res
		(visitor.visit(self) != MatchError) || res
	end
end