From: jweirich@... Date: 2001-07-24T11:45:22+09:00 Subject: [ruby-talk:18401] Re: interfaces? >>>>> "MikkelFJ" == MikkelFJ writes: MikkelFJ> Are there interfaces in Ruby? If not, why not? MikkelFJ> However, I would like to be able to query an object MikkelFJ> about an interface, such that I know I can trust it to MikkelFJ> do the expected. MikkelFJ> shape_collection.each do |obj| MikkelFJ> case obj MikkelFJ> when IRayIntersection MikkelFJ> clip_using_interface(obj) MikkelFJ> when Box MikkelFJ> clip_as_rectangle(obj) MikkelFJ> when Sphere MikkelFJ> clip_as_circle(obj) MikkelFJ> end MikkelFJ> end Assuming the choice of clipping algorithm rests solely in the type of Shape, then moving the clipping algorithm into the shape objects make a lot of sense. Then your code will look like ... shape_collection.each { |shape| shape.clip } If a BoxWithHole can't use the standard box algorithm, it will implement the IRayIntersection algorithm for its version of clip. No need to search a list of possible algorithms. Best of all, if you add a new algorithm there is no need to update this case statement (and any others you might have). On the other hand, it is possible that the choice of clipping algorithm is dependent upon both the sender and receiver. In other words, clipping a box against a box is different than clipping a circle against a box, which in turn is different from circle/circle clipping. This is a tougher problem. One possibility is using a double dispatch setup like this (sorry about the long example) ... # START CODE --------------------------------------------------------- module ClippingAlgorithms def box_circle_clip(box, circle) puts "Box/Circle Clipping" end def circle_circle_clip(circle1, circle2) puts "Circle/Circle Clipping" end def box_box_clip(box1, box2) puts "Box/Box Clipping" end end class Circle include ClippingAlgorithms def clip(other) other.circle_clip(self) end def circle_clip(circle) circle_circle_clip(self, circle) end def box_clip(box) box_circle_clip(box, self) end end class Box include ClippingAlgorithms def clip(other) other.box_clip(self) end def circle_clip(circle) box_circle_clip(self, circle) end def box_clip(box) box_box_clip(self, box) end end b = Box.new c = Circle.new b.clip(b) #=> Box/Box Clipping c.clip(c) #=> Circle/Circle Clipping b.clip(c) #=> Box/Circle Clipping c.clip(b) #=> Box/Circle Clipping # END CODE ----------------------------------------------------------- The downside is that adding new shapes causes an explosion of new combinations. Sometimes this can be mitigated through judicious use of inheritance. If you don't need the complexity, obviously the first solution is much better. -- -- Jim Weirich jweirich@one.net http://w3.one.net/~jweirich --------------------------------------------------------------------- "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)