Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
The Visitor Pattern implementation in Ruby from the Wikipedia example
class CarElement
def accept(visitor)
raise NotImpelementedError.new
end
end
module Visitable
def accept(visitor)
visitor.visit(self)
end
end
class Wheel < CarElement
include Visitable
attr_reader :name
def initialize(name)
@name = name
end
end
class Engine < CarElement
include Visitable
end
class Body < CarElement
include Visitable
end
class Car < CarElement
def initialize
@elements = []
@elements << Wheel.new("front left")
@elements << Wheel.new("front right")
@elements << Wheel.new("back left")
@elements << Wheel.new("back right")
@elements << Body.new
@elements << Engine.new
end
def accept(visitor)
@elements.each do |element|
element.accept(visitor)
end
visitor.visit(self)
end
end
class CarElementPrintVisitor
def visit(subject)
puts "Visiting: %s" % subject.class.to_s
end
end
class CarElementDoVisitor
def visit(subject)
puts "Do some other visitation: %s" % subject.class.to_s
end
end
c = Car.new
c.accept(CarElementPrintVisitor.new)
c.accept(CarElementDoVisitor.new)
@mlohr

This comment has been minimized.

Copy link

@mlohr mlohr commented May 23, 2013

Thanks heaps for this example, just what I am looking for!

@TomazMartins

This comment has been minimized.

Copy link

@TomazMartins TomazMartins commented May 25, 2015

Thanks for this example!

@nahurfonseca

This comment has been minimized.

Copy link

@nahurfonseca nahurfonseca commented Apr 1, 2016

Thanks, but this example does not quite accomplishes the visitor pattern. See this other post:
http://blog.bigbinary.com/2013/07/07/visitor-pattern-and-double-dispatch.html

And this example from Arel (used in Rails / ActiveRecrdr):
https://github.com/rails/arel/blob/master/lib/arel/visitors/visitor.rb

The key difference with ruby (from other languages like C++ and Java) is that we cannot overload methods with different signatures, we need to create new methods names that encodes the desired signature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment