As an exercise for myself, I was translating a sample program into various languages. Starting in C#, I had a visitor-pattern interface like so:
interface Visitor
{
void Accept(Bedroom x);
void Accept(Bathroom x);
void Accept(Kitchen x);
void Accept(LivingRoom x);
}
Moving to ruby (or python, or whatever), I no longer get dispatch from the compiler based on type. Should I do the dispatch in the visitor itself?
class Cleaner
def accept(x)
acceptBedroom(x) if Bedroom === x
acceptBathroom(x) if Bathroom === x
acceptKitchen(x) if Kitchen===x
acceptLivingRoom(x) if LivingRoom===x
end
...
Or should I do the dispatch in the different specializaions of the room:
class Bathroom<Room
def initialize(name)
super(name)
end
def accept(visitor)
visitor.acceptBathroom(self)
end
end
Or is there another preferred idiom that is used in dynamic languages?
My recommendation is to use the former approach. There are pluses and minuses for each approach. The former is harder to maintain as the number of Room types grows; the latter is harder as the number of Cleaner types grows.
In Ruby, you could try
def accept(x)
send "accept#{x.class}".to_sym, x
end
PS: not all dynamically typed languages are unable to do dispatch based on type; some can infer type, or failing that, can used forced casting to pick the proper method among the overloaded options.