1: http://www.ruby-doc.org/core-1.9/classes/BasicObject.html
I've used dozens of Ruby gems, plugins and classes over the years that have well-documented shared APIs and none of them (obviously) have had interfaces. Interfaces are good in certain environments for hiding implementation details where class-level contracts are enforced, but in Ruby this would provide no benefit at all.
Think of it this way: since Ruby has no class-level contracts, to some extent everything is already an interface. Everything is abstract. Every Ruby object has the opportunity to re-implement functionality in an abstract way.
You get exactly the same benefits as you would from an interface (minus the rigidity)...
That said, yes, Ruby with interfaces seems kind of pointless and is just throwing more code in, which is the opposite of one of the nicer points of the language.
http://pypi.python.org/pypi/zope.interface http://docs.python.org/library/abc.html
I looked quickly at pep-3119 and it seems like it's a short-hand way of checking if an object will respond to some set of methods.
Now, I cop to having done type checking in Ruby (either with is_a? or respond_to?) but I always felt it was a code smell, a hack to solve a distraction while I moved on to something else more pressing.
I don't know a whole lot of Python, but I'm guessing that since Python has a more Java-like form of OOP (i.e., method invocation vs. the message passing of Ruby, a la Smalltalk) this kind of type-checking is quite acceptable, even though Python is ostensibly duck-typed.
Am I wrong, and by how much?
Generally, checking the type with isinstance is considered bad practice although it can be useful sometimes (I can't think of any simple examples off the top of my head though).
The main reason I can think of for using an interface or abc is simply so that if you forget to add a required method, the exception gets thrown sooner rather than later. Plus with an abc, you also allow the base class to define methods that depend upon abstract methods (for instance, if you subclass the Mapping abc, you get __contains__, keys, items, etc for adding __getitem__). Strictly speaking, there's no reason why you can't do that without an abstract base class, but it makes it easier.
In short, there are useful reasons to have interfaces and abstract base classes in Python, but they probably aren't the same reasons you'd want them in a statically-typed language like Java.
http://twistedmatrix.com/documents/current/core/howto/compon...
If you're in a hurry, the main motivations appear to be:
- declaring that a class supports particular functionality without risking the complications of multiple inheritance - the ability to register adapters from one interface to another means no more calls to isinstance() (or at least, they're abstracted away to a library function) - Easy to make your test suite check that you haven't forgotten to implement any methods of any of the interfaces your class claims to support.
You can pick out a set of objects that implement a certain interface from a larger set. You can do this for classes, objects, perhaps modules.
Someone already mentioned Twisted plugins. They currently use Zope interfaces. You create a class then declare that it implements a particular interfaces.
Haskell type classes seem, to me, to take the right approach here as well. In fact I would argue their main benefit is not catching programmer error - but encouraging thoughtful design.
In Eclipse it's as simple as using the refactor tool to 'pull up interface' from any God Class of my choosing.
Neither language nor framework can force a coder to apply the Single Responsibility Principle. Coders can be willy-nilly with or without interfaces.
What mechanism would enforce the contract anyway? The best you could hope for would be a runtime error thrown when the interpreter detected the incompatibility, and you can do that manually now (I do it frequently to imitate abstract classes).
class IAnimal
def growl
raise
end
endNow, many languages with formal interfaces (e.g., Java) are strongly typed, and they treat interfaces as types. Thus, for example, classes have to declare up front what interfaces they implement. That doesn't fit well with the flexible attitude of a duck-typed language. However, if interfaces were just collections of method signatures that could be tested against objects at runtime, that would be perfectly compatible with duck typing.
Languages like Modula-3 that use structural type equivalence sort of do this even in a strongly-typed system. Sort of.
Interfaces are useful in defining what an implementor must provide, but an example implementation does this as well.
Also, if it helps, just think of the impl as an interface with a default behaviour that should be overriden ;)
If this is too forgiving, then we can even have the impl methods throw errors ("override me!") and simulate an interface.
someMethod
self subclassResponsibility
and then use the realize class refactoring on a subclass to generate stubs for all methods I must implement, just like an interface.What I was trying to get to: if you accept the existence of single-method ducktypes (like "things that have a walk() method" oder "things that have a quack() method"), then by intersecting these concepts, you arrive at things just like interfaces, whether you call them interfaces or not. If you want the pond system to work with your two-legged bird-sound robot, you perform the same mental steps as when implementing an interface. Hence, ducktypes could be seen as interfaces without an instanceof-operation.
For example, a hash-based collection might require that all its members implement an equality method and a hash method. Typically in Ruby you test this by just waiting for one of those method calls to blow up somewhere in the hash table code. Instead, you could test "acts_like?(Hashable)" -- meaning "reaponds_to?(:=) && responds_to?(:hash)" -- on insertion. Then you could give a nice, meaningful error message at a nice point in the code.
Note that this has nothing whatsoever to do with is_a?, which is the important difference between this and type-based interfaces as in Java.