Module vs. class distinctions

Given that Ilias lately asks so many pseudo-intellectual questions, I’ve
been thinking that I could do the same.

Basically, my gripe is that Ruby separates behaviour into module and
classes.

It is extremely typical to see code like:

module Foo
class Bar

Foo::Bar.new

Now, let’s model an animal hierarchy for a moment …

class Animal

has some code

class Cat < Animal

has some code

class Dog < Animal

has some code

class Fox < Animal

has some code

Ok, they all use Animal. But is it really needed to subclass like that?
Wouldn’t it be just as useful to do this:

class Animal

class Cat
include Animal

class Dog
include Animal

And so on? In other words to include another class into a class, just as
if it were a module.

But it could be simplified even more. Why is there any distinction
between class and module, seriously?

module Animal

define some common methods

class Cat
include Animal

Of course because a module is an incomplete class only. It won’t have
instance variables and so on. But why not? It is just behaviour after
all, and a class that includes a module can behave differently
afterwards, almost the same way as you get by subclassing.

I feel that when I think about subclassing, I just restrict the way I
model something. It only follows a one-way path, down the line.

Animal -> Cat -> Tom

Tom the cat.

He would have the functionality of Cat and Animals.

But what if Tom also wants to be… let’s say … an undead cat?

Well … I guess being an undead cat, one would have to be a module.

module Undead

Animal -> Cat -> Tom -> include Undead

Or of course, Cat could be changed to UndeadCat

Animal -> UndeadCat -> Tom

But that would force me to use a new cat type, and I’d rather do that
differently too.

Animal -> Cat -> include Undead -> Tom

I am not sure if I am making a lot of sense here.

My main questions are:

  • Why is there a real distinction between module and class in Ruby in
    the first place?

  • What advantages does that bring, or rather, why would it be not
    possible to harmonize both class and modules into the same thing,
    behaviours or traits? (Or perhaps, to think of Ruby as a prototype based
    language and just use traits to extend those objects WITHOUT any
    subclassing )

Marc H. wrote in post #1006476:

My main questions are:

  • Why is there a real distinction between module and class in Ruby in
    the first place?
  • What advantages does that bring, or rather, why would it be not
    possible to harmonize both class and modules into the same thing,

There’s a distinction because they serve different purposes. Why is
there a for loop and an iterator? They appear to be the same thing but
they have different purposes. Same for classes and modules. They appear
very similar, but serve very unique purposes.

There’s a number of tactical advantages in using a module, but I think
the big picture boils down to the more strategic avoidance of the mess
that multiple inheritence abuse can create, and it is an effective work
around to the limitations of hard-core, single-class inheritence.
Neither extreme is very desirable, so there needs to be a middle ground
of some kind. Modules is a solution to finding that middle ground, and
it seems to work quite well. I’m sure experienced folks with
multi-inheritance languages have learned some patterns to make it work
well, but it seems like most debates about it suggest that it causes
more problems with the populace than it is worth. You can read the
debates and play with something like C++ to discover the issues.

Read the Modules chapter of any Ruby programming book, or hunt the blogs
for more in depth discussion as to why modules. It can take a few
examples and scenarios to acquire the big picture of how elegant a
solution/tool it is.

BTW…

module Foo
class Bar

The purpose of that is name spacing so that two different systems of
code can both have a class named Bar. In this case it would actually be
called as Foo::Bar to distinguish which Bar.

module Cms
class User
end
end

module Admin
class User
end
end

Now your app, can have Cms::User and Admin::User. Both can be used
without stepping on the other’s toes.

More BTW…

class Animal

has some code

class Cat < Animal

has some code

class Dog < Animal

has some code

class Fox < Animal

has some code

Ok, they all use Animal. But is it really needed to subclass like that?

“Needed” – depends on goals of the code.

Wouldn’t it be just as useful to do this:

class Animal

class Cat
include Animal

class Dog
include Animal

Well, you’re close, it would be:

module Animal

class Cat
include Animal

class Dog
include Animal

The stuff that is common to multiple classes is what would go into a
module. This provides the flexibility of code sharing among classes
without the baggage of multiple inheritence (research that term). It
also allows a class to retain a simple, flat API vs requiring the use of
composition where composition doesn’t really fit.

So, we could have Dog.bark and Cat.meow but share the code for
Dog.has_tail? and Cat.has_tail? in the module. As far as the coder is
concerned, .has_tail? is simply a part of the Dog and Cat API just like
.bark and .meow.

At that simple a level, multi-inheritence and modules may seem
identical. So, you’ll have to explore the more esoteric examples in the
debates to understand how they ultimately end up being different.

– gw