# 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")) <