"MikkelFJ" <mikkelj-anti-spam / post1.dknet.dk> writes:

> Some time back I asked a question about interfaces in Ruby. The
> conclusion was, that you could check the module using is_a. You
> could even create empty modules to define an interface.  For some
> purposes I think this is the right approach. You could for example
> include a module BasicContainer in the triple class, which could be
> tested.

Except there's no type involved. At best it's a convention.

   is_a? Array

guarantees nothing about the object you are testing other than it is
part of Array's class tree.

The use of null mixins as flags is different. Here we're not looking
for a type (in terms of operations supported), but simply the presence
of the flag itself. That's fine. But hoping to determine what operations
are accepted based on an object's class is suboptimal.

I think it's poor form for two reasons. First, just because an object
has a type of Array doesn't mean it has the semantics of some
abstracted Array class. As you know, the programmer can mess with the
semantics of either the entire class Array or with a particular
object. Object#type gives you a pedigree, not a type.

The second reason it's poor form is that it artificially limits your
program's applicability. Look at the Shuffle example: the author said
"this only works on Arrays" and put in an assertion to that
effect. But that wasn't true: Shuffle worked on any object with
#length and #[].

> A test for is_a(Array) or is_a(BasicContainer) would then be
> appropriate if you want to do some type checking.

If you want to do type testing, you should really use #respond_to?,
not #is_a?, as that way you'll make explicit the operations that
you're asking your object to have.

Again, though, I'd question the usefulness of this.  What is the
benefit of having an application die with an assertion failure at the
top of a routine, when it will fail anyway with a NameError a few
lines down?


Dave