62 lines
1.5 KiB
Ruby
62 lines
1.5 KiB
Ruby
# Represent an operation to be performed on the elements of an object structure.
|
|
# Visitor lets a new operation be defined without changing the classes of the
|
|
# elements on which it operates.
|
|
|
|
module Node
|
|
def accept visitor
|
|
if self.kind_of? StringNode
|
|
visitor.visit_string self if visitor.respond_to? :visit_string
|
|
elsif self.kind_of? IntegerNode
|
|
visitor.visit_int self if visitor.respond_to? :visit_int
|
|
end
|
|
end
|
|
end
|
|
|
|
class StringNode
|
|
include Node
|
|
attr_accessor :string
|
|
|
|
def initialize(val)
|
|
@string = val
|
|
end
|
|
end
|
|
|
|
class IntegerNode
|
|
include Node
|
|
attr_accessor :int
|
|
|
|
def initialize(val)
|
|
@int = val
|
|
end
|
|
end
|
|
|
|
class PrintingVisitor
|
|
def visit_string(node)
|
|
puts node.string
|
|
end
|
|
def visit_int(node)
|
|
puts node.int
|
|
end
|
|
end
|
|
|
|
class RevertingVisitor
|
|
def visit_string(node)
|
|
puts node.string.reverse!
|
|
end
|
|
end
|
|
|
|
# Usage
|
|
myTreeRoot = Tree::TreeNode.new("ROOT", StringNode.new("this is the root node"))
|
|
|
|
myTreeRoot << Tree::TreeNode.new("child1", StringNode.new("madam im adam")) << Tree::TreeNode.new("grandchild1", IntegerNode.new(3)) << Tree::TreeNode.new("grandchild2", IntegerNode.new(2))
|
|
myTreeRoot << Tree::TreeNode.new("child2", StringNode.new("race car")) <<Tree::TreeNode.new("grandchild3", StringNode.new("damn, i agassi miss again. mad"))
|
|
|
|
puts "PRINTING visitor..."
|
|
@pvisitor = PrintingVisitor.new
|
|
myTreeRoot.each { |node| node.content.accept @pvisitor }
|
|
puts "\nREVERTING visitor..."
|
|
|
|
@rvisitor = RevertingVisitor.new
|
|
myTreeRoot.each { |node| node.content.accept @rvisitor }
|
|
|