How are mixins better than multiple inheritance?

B

Bill Atkins

Can anyone explain how Ruby's mixin system is better than regular
multiple inheritance? What's the difference between:

----

module Parent1
def amb_func
puts "in parent1"
end
end

module Parent2
def amb_func
puts "in parent2"
end
end

class Child
include Parent1, Parent2
end

Child.new.amb_func

----

and

----

class Parent1
def amb_func
puts "in parent1"
end
end

class Parent2
def amb_func
puts "in parent2"
end
end

class Child < Parent1, Parent2
end

Child.new.amb_func

---

Aside from the fact that the second example obviously isn't valid
Ruby, how is the first scenario an improvement over the second? The
first outputs "in parent2" and I assume the second would as well. Can
somebody please explain this?

Bill
 
Y

Yukihiro Matsumoto

Hi,

In message "How are mixins better than multiple inheritance?"

|Can anyone explain how Ruby's mixin system is better than regular
|multiple inheritance? What's the difference between:

Mix-in is no better than multiple inheritance, because mix-in is just a
usage of multiple inheritance. You can do mix-in by multiple
inheritance. Ruby forces mix-in to make it hard to "abuse" multiple
inheritance.

matz.
 
S

Sean Russell

Mix-in is no better than multiple inheritance, because mix-in is just a
usage of multiple inheritance. You can do mix-in by multiple
inheritance. Ruby forces mix-in to make it hard to "abuse" multiple
inheritance.

The difference for me has been mainly conceptual. I consider mixins
to be:

* Primarily functional. You're mixing in functions.
* Stateless. There are no class-level variables with mixins.
* Mixins anticipate and make use of methods in some future class that
mixes them in.

As assertions, these are patently untrue; you can end up mixing in
class-level variables in Ruby, and the mixed in methods don't ever
have to access any external methods. However, these are the
characteristics that I generally associate with mixins.

Inheritance, multiple or single, has different general
characteristics:

* Stateful. You are inheriting not only behavior, but state.
* Ignorance on the inheritee of the inheritor.

In Ruby, there is nothing that you can do with one that you can't do
with the other -- except for multiplicity -- so there is no practical
difference. I believe that the conceptual difference is useful,
though.

--- SER
 
G

Georgy

Hm, mine outputs "in parent1"

module Parent1
def amb_func
puts "in parent1"
end
end

module Parent2
def amb_func
puts "in parent2"
end
end

class Child
include Parent1, Parent2
end

Child.new.amb_func #=> in parent1

___
Georgy

| Can anyone explain how Ruby's mixin system is better than regular
| multiple inheritance? What's the difference between:
|
| ----
|
| module Parent1
| def amb_func
| puts "in parent1"
| end
| end
|
| module Parent2
| def amb_func
| puts "in parent2"
| end
| end
|
| class Child
| include Parent1, Parent2
| end
|
| Child.new.amb_func
|
| ----
|
| and
|
| ----
|
| class Parent1
| def amb_func
| puts "in parent1"
| end
| end
|
| class Parent2
| def amb_func
| puts "in parent2"
| end
| end
|
| class Child < Parent1, Parent2
| end
|
| Child.new.amb_func
|
| ---
|
| Aside from the fact that the second example obviously isn't valid
| Ruby, how is the first scenario an improvement over the second? The
| first outputs "in parent2" and I assume the second would as well. Can
| somebody please explain this?
|
| Bill
 
R

Robert Klemme

Georgy said:
Hm, mine outputs "in parent1"

module Parent1
def amb_func
puts "in parent1"
end
end

module Parent2
def amb_func
puts "in parent2"
end
end

class Child
include Parent1, Parent2
end

Child.new.amb_func #=> in parent1
=> [Child, Parent1, Parent2, Object, Kernel]

That's why. See:
?> Child1.ancestors
=> [Child1, Parent1, Parent2, Object, Kernel]
Child2.ancestors => [Child2, Parent2, Parent1, Object, Kernel]

Apparently the inclusion sequence differs if you have two separate include
statements vs. one statement with two modules.

Regards

robert
 
G

Georgy

|
| Apparently the inclusion sequence differs if you have two separate include
| statements vs. one statement with two modules.
|

Yes, I thought so (and tested all variants indeed), but OP had posted
the same code I tryed, and had different output. Probably the behavior
of this construction is not defined by the language. Or he just didn't try
his own code.
---
Georgy

| | > | Can anyone explain how Ruby's mixin system is better than regular
| > | multiple inheritance? What's the difference between:
| > |
| > | ----
| > |
| > | module Parent1
| > | def amb_func
| > | puts "in parent1"
| > | end
| > | end
| > |
| > | module Parent2
| > | def amb_func
| > | puts "in parent2"
| > | end
| > | end
| > |
| > | class Child
| > | include Parent1, Parent2
| > | end
| > |
| > | Child.new.amb_func
| > |
| > | ----
| > |
| > | and
| > |
| > | ----
| > |
| > | class Parent1
| > | def amb_func
| > | puts "in parent1"
| > | end
| > | end
| > |
| > | class Parent2
| > | def amb_func
| > | puts "in parent2"
| > | end
| > | end
| > |
| > | class Child < Parent1, Parent2
| > | end
| > |
| > | Child.new.amb_func
| > |
| > | ---
| > |
| > | Aside from the fact that the second example obviously isn't valid
| > | Ruby, how is the first scenario an improvement over the second? The
| > | first outputs "in parent2" and I assume the second would as well. Can
| > | somebody please explain this?
| > |
| > | Bill
| >
| >
|
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top