On Tuesday 27 April 2010 11:52:08 am Bernhard B. wrote:
Hi,
I heard many times that the visitor pattern is useless in Ruby and
similar things.
At a glance, it seems to me that the visitor pattern is born directly
out of
two things: A staticly-typed language, and the lack of proper closures.
This would have another advantage, namely that I can easily add more
visitors, like for example a pretty printer or something to compare ASTs
(useful for unit tests)
I could just add this functionality to the elements of the AST directly,
but somehow, I don’t like this because I always have to search my ~30
classes that represent syntax units and implement one method in each of
them. Instead, it’s much more comfortable to just write one new class.
Well, it seems like a lot of this would be re-usable, hopefully through
inheritance. In fact, if your unit tests are just comparing whether two
ASTs
are identical, I bet you can figure out a completely generic way to do
that,
as a single method on your base class.
And yes, it’s going to be a ginormous case statement anyway. I’d much
rather
use polymorphism than case statements any day.
What do you think about that? Is it really that bad to use the visitor
pattern in Ruby? And if yes, what is the reason for this?
I suspect it’s bad in the same way that this is bad:
i = 0
while i < array.length
puts array[i]
i += 1
end
That is, I bet it’d work fine, and there may well be some cases where it
makes
sense – for instance, sometimes you really do need an index that you
can
arbitrarily manipulate (that is, sometimes even each_with_index isn’t
good
enough) – but it just seems like a weird approach, and not very
idiomatic.
In particular, I assume your “visitor” would be examining the type
(class) of
each object? In anything other than a pretty-printer, aside from being a
big
nasty case statement, it’s also the opposite of duck-typing.
I could be wrong. I think Ruby’s enumerables are better than Java’s
iterators
most of the time, but Ruby’s enumerators are basically Java’s iterators,
and
they are sometimes ridiculously useful.