Skip to content

Instantly share code, notes, and snippets.

@adomokos
Created May 24, 2011 17:28
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save adomokos/989193 to your computer and use it in GitHub Desktop.
Save adomokos/989193 to your computer and use it in GitHub Desktop.
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
Copy link

mlohr commented May 23, 2013

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

@TomazMartins
Copy link

Thanks for this example!

@nahurfonseca
Copy link

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