On Wednesday 23 February 2005 09:58 pm, Sam Roberts wrote:
> > You could do ...
> >
> > class A
> > def do_something() ... end
> > end
> > class B
> > def do_something() ... end
> > end
> >
> > t.do_something
>
> I know where you are coming from, this is a nice pattern, but in this
> case t is a return value of Resolv:
NS::Message#question, and I have to
> answer the question. How I answer the question depends on the question
> (of course!), but is not part of the behaviour of the question,
> different "answers" answer the question in different ways.
I'm not sure if you are saying that won't work because (1) the do_something
method is not part of the behavior of the classes in question, or (2) you
need to respond differently to these classes in different circumstances. Or
perhaps both (1) and (2) are the case.
If (1), then remember that you can always open up any class and add more
behavior.
If (2), then you can do something like the following (simple visitor pattern):
module Kernel
def accept_visitor(visitor)
visitor.send("visit_" + self.class.name.downcase.gsub(/::/, '_'), self)
end
end
class A; end
class B; end
class MySpecialVisitor
def visit_a(a)
puts "Doing something with A: (#{a})"
end
def visit_b(b)
puts "Doing something else with B: (#{b})"
end
end
A.new.accept_visitor(MySpecialVisitor.new)
B.new.accept_visitor(MySpecialVisitor.new)
You can define as many visitors as you need to get the varied behaviors
required by your problem.
The solution is a bit more complicated, but allows open-ended behaviors for
any class.
--
-- Jim Weirich
http://onestepback.org
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)