Class: TreeRb::TreeNodeVisitor

Inherits:
Object
  • Object
show all
Defined in:
lib/tree_rb/core/tree_node_visitor.rb

Overview

More complex TreeNodeVisitor, define a simple dsl

Examples:

TreeNodeVisitor.new do
  on_enter_node do |node|
    puts "hello #{node}"
  end
  on_exit_node do |node|
    puts "bye #{node}"
  end
  on_leaf do |leaf|
    puts "how you do #{leaf}"
  end
end

Instance Method Summary collapse

Constructor Details

#initialize(delegate = nil, &block) ⇒ TreeNodeVisitor

Returns a new instance of TreeNodeVisitor.

Parameters:

  • delegate (Object) (defaults to: nil)


22
23
24
25
26
27
28
29
30
31
32
# File 'lib/tree_rb/core/tree_node_visitor.rb', line 22

def initialize(delegate = nil, &block)
  @on_enter_tree_node_blocks = []
  @on_exit_tree_node_blocks  = []
  @on_visit_leaf_node_blocks = []
  @stack                     = []
  @root                      = nil
  @delegate                  = delegate
  if block
    instance_eval(&block)
  end
end

Instance Method Details

#cannot_enter_node(tree_node, error) ⇒ Object

called when the tree node is not accessible or an exception is raise when the node is accessed

Parameters:

  • error (Object)


58
59
# File 'lib/tree_rb/core/tree_node_visitor.rb', line 58

def cannot_enter_node( tree_node, error)
end

#enter_node(tree_node) ⇒ Object

called on tree node at start of the visit i.e. we start to visit the subtree



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/tree_rb/core/tree_node_visitor.rb', line 37

def enter_node(tree_node)
  parent = @stack.last
  if @delegate
    @delegate.enter_node(tree_node) if @delegate.respond_to? :enter_node
  else
    @on_enter_tree_node_blocks.each do |b|
      if b.arity == 1
        b.call(tree_node)
      elsif b.arity == 2
        b.call(tree_node, parent)
      end
    end
  end
  @root = tree_node if @stack.empty?
  @stack.push(tree_node)
end

#exit_node(tree_node) ⇒ Object

called on tree node at end of the visit i.e. oll subtree are visited



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/tree_rb/core/tree_node_visitor.rb', line 64

def exit_node(tree_node)
  parent = @stack.last
  if @delegate
    @delegate.exit_node(tree_node) if @delegate.respond_to? :exit_node
  else
    @on_exit_tree_node_blocks.each do |b|
      if b.arity == 1
        b.call(tree_node)
      elsif b.arity == 2
        b.call(tree_node, parent)
      end
    end
  end
  @stack.pop
end

#on_enter_node(&block) ⇒ Object

add a block to be called when entering into a tree_node



101
102
103
104
105
# File 'lib/tree_rb/core/tree_node_visitor.rb', line 101

def on_enter_node(&block)
  raise 'already defined a delegate' if @delegate
  raise 'block missing' unless block
  @on_enter_tree_node_blocks << block
end

#on_exit_node(&block) ⇒ Object

add a block to be called when exiting from a TreeNode



110
111
112
113
114
# File 'lib/tree_rb/core/tree_node_visitor.rb', line 110

def on_exit_node(&block)
  raise 'already defined a delegate' if @delegate
  raise 'block missing' unless block
  @on_exit_tree_node_blocks << block
end

#on_leaf(&block) ⇒ Object

add a block to be called when visiting a leaf node



119
120
121
122
123
# File 'lib/tree_rb/core/tree_node_visitor.rb', line 119

def on_leaf(&block)
  raise 'already defined a delegate' if @delegate
  raise 'block missing' unless block
  @on_visit_leaf_node_blocks << block
end

#visit_leaf(leaf_node) ⇒ Object

called when visit leaf node



83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/tree_rb/core/tree_node_visitor.rb', line 83

def visit_leaf(leaf_node)
  parent = @stack.last
  if @delegate
    @delegate.visit_leaf(leaf_node) if @delegate.respond_to? :visit_leaf
  else
    @on_visit_leaf_node_blocks.each do |b|
      if b.arity == 1
        b.call(leaf_node)
      elsif b.arity == 2
        b.call(leaf_node, parent)
      end
    end
  end
end