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.



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