Created
May 24, 2011 17:28
-
-
Save adomokos/989193 to your computer and use it in GitHub Desktop.
The Visitor Pattern implementation in Ruby from the Wikipedia example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
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
Thanks for this example!