Like Java and unlike Python, Ruby does not support multiple inheritance. Also there is no explicit way to create an interface. One way Ruby lets you get around both problems is by allowing you to include a module in a class. It’s not quite the same, but with the proper planning you can duplicate the functionality. Of course, one question you should always ask yourself when trying to shoehorn something from one language into another is if you’re really going about it the right way.
One way of implementing a Java-like interface in Ruby is by creating a module containing the skeleton functions you want the implementing class to implement.
module A def method1() raise "not supported"; end end class B include A def method1 puts "now implemented" end end
Presto, module A is basically a Java interface. Of course, whether a method has been implemented is not checked until runtime when the method is actually called. Also if you mix in implemented methods alongside the interface methods, you have something very like an abstract class (minus the compile-time checking).
This came up when I was implementing a bunch of simple tree functions like finding the siblings of a node, finding the grandparent, the descendants, the leaves of a subtree, etc. It seemed like these were things that should be implemented already. And why not? So I threw all of those methods into a module and made it like a Java abstract class. All you have to implement is a method to call the parent of the current node (or return
nil if there is none) and a method to get an
Array of the children of the current node. Your class can pull children from a database, a file, something more complex — it doesn’t matter. Just implement those two methods and drop in the SimpleTree module and problem solved.
Since I’ve been having fun with gems, I made one for this and slapped it up on GitHub. To get it, just type:
sudo gem install ealdent-simple-tree
Assuming that you have already done this as some point in the past:
gem sources -a http://gems.github.com
Feel free to extend it, modify it, contribute to it, etc. I’m using the BSD license, which is my current favorite.