But as to the issue of partially-implemented interfaces, I
think they’re fine. One IO interface is all you need.
If you have an object that is input-only and sequential,
and the base IO interface allows for more, then your class is
simply not going to implement them.
Ah, the solution to an over constrained system is to ignore the constraints.
[… From another message …]
now you know it responds to open, close, read, write, select,
etc. and you know what parameters they take.
Actually, you don’t know that because it may be a partially implemented
interface.
kind_of? indicates that it belongs to a pre-described interface (a
contract),
with a fixed collection of methods with parameters which are also known.
An interface (at least a Java style interface) is a poor substitute for a
contract (I can recommend some good Design by Contract material if you are
unfamiliar with DbC). An interface is merely a list of method names and
their parameters and says nothing about the semantics of an operation.
If the presence of the interface tag in the inheritance graph of an object
doesn’t guarantee behavior, then why bother checking for it? If partially
implemented interfaces are fine, then you still need to deal with the issue
of figuring out what portion of the interface constitutes “fine”.
What I suspect is that you when you write a function, you would like to
communicate things like …
- function foo expects a parameter that conforms to the “socket” protocol.
And I actually tend to agree with the desire to communicate. However,
making an explicit test for inheriting from a particular module or class is
a poor way to communicate this. Although you get /slightly/ better
diagnostics when you goof up, those slightly better diagnostics come at a
cost. The cost is excessive, unneeded runtime checking, needlessly limited
options on what kind of parameters a method accepts, and extra design
overhead (i.e. the need to explicitly identify abstract protocols that may
or may not be needed). And in the end, the goal of communication is not
served because the test is buried in the /code/ of the method, not in the
interface itself. A well named parameter or an RDOC comment both serve to
put the information in the interface (and in the browsable documentation)
where the buried kind_of? test will not.
···
–
– Jim Weirich