2010-10-27 14 views
11

Matz supuestamente dijo "mixins podían hacer casi todo lo que la herencia múltiple hacer, sin los inconvenientes asociados" (palabras Matz)."¿Cómo es que la inclusión del módulo Ruby no es realmente "herencia múltiple" y cómo el estilo Ruby evita los problemas asociados con la herencia múltiple?

En primer lugar, ¿por qué es Rubí inclusión módulo no 'herencia múltiple'? Me parece que hay es muy poca diferencia entre módulos y clases. El hecho de que no se pueda instanciar un módulo es irrelevante cuando se usa como una superclase.

También sé que la sucesiva inclusión de módulos forma una cadena de herencia única (no árbol) que se extiende hacia arriba desde clase. Pero esto, para mí, no es suficiente para distinguirlo de la "herencia múltiple" ya que el sistema de herencia múltiple de Python también "linealiza" la cadena de la superclase (usando el C3 algorithm) es solo que el proceso de "linearización" de Ruby es significativamente más simple.

Entonces, ¿qué distingue exactamente las mezclas de módulos de Ruby de la herencia múltiple en, por ejemplo, un lenguaje como Python? ¿Y por qué los argumentos detrás de la adopción de Python del algoritmo c3 MRO no se aplican a Ruby? Y si se aplican, ¿por qué Ruby decidió no adoptar este algoritmo?

gracias

+6

Aquí es un buen artículo sobre el caso, ver si responde a tu pregunta: http://www.artima.com/weblogs/viewpost.jsp?thread=246488 –

+0

@Mladen esto es absolutamente brillante ... si lo agregas como una respuesta correcta, 'aceptaré' 'it :) – horseyguy

Respuesta

3

Agregando esto en nombre de Mladen como una respuesta real, porque me pareció muy útil, y supongo que las respuestas se indexan mejor para las locuras que SO haga con ellas.

Aquí es un buen artículo sobre el caso, ver si responde a su pregunta: http://artima.com/weblogs/viewpost.jsp?thread=246488 - Mladen Jablanović 28 '10 de octubre a las 18:23

0

compruebas el libro de "Metaprogramación Rubí" de la prensa pragmático. Contiene una explicación muy detallada de esto, de una manera que es muy fácil de leer y entender. http://pragprog.com/titles/ppmetr/metaprogramming-ruby

No puedo responder el mot de sus preguntas porque no conozco python. pero lo básico de por qué no es una herencia múltiple es que Ruby inyecta el módulo en la cadena de herencia cuando se incluye el módulo o una clase se extiende por un módulo.

class Foo 
    include Bar 
end 

module Bar 
end 

foo = Foo.new 

Esto produce una cadena de herencia donde foo es una instancia de Foo y Foo hereda de Bar.

es un poco más complicado que eso, y hay reglas para el orden en el que se produce la inyección de herencia. el libro que mencioné lo explica muy bien.

+0

Gracias, jeje, pero ¿crees que podrías resumir con más detalle lo que dice el libro? Nota: No necesito saber los detalles de cómo se inyecta el módulo, más la teoría detrás de por qué eligieron este enfoque sobre el enfoque típico de herencia múltiple y CÓMO es diferente al enfoque MI normal. :) Perdón por preguntar, pero no voy a comprar este libro (ya tengo demasiados para leer jeje). – horseyguy

+0

He leído "Metaprogramación Ruby", y no sé la respuesta a la pregunta de barandilla. –

0

Lo más importante en ruby ​​es sobrescribir definiciones previas de datos/funciones con cada módulo incluido.

Por lo tanto, es malo, ya que cada nuevo módulo debe tener en cuenta teóricamente el acceso al código anterior que se sobrescribe.

Así código de ejemplo para escribir nuevo módulo es (lógicamente):

old_function = fun 
fun = define_new_function 
    do_you_staff 
    call old_function 

Usted no tiene que utilizar la función de edad, aunque en la mayoría de los casos es útil, pero a veces es más fácil volver a escribir todo el código.

Cada módulo incluido creará una cadena de métodos sobrescritos, por lo que no habrá problemas con la herencia múltiple, pero el orden de incluir módulos se vuelve más importante.

Este método también se conoce como parche de monos, término ampliamente utilizado en Ruby on Rails.

4

Con MI, muchos de los problemas que surgen pueden reducirse a detalles de implementación; no se puede hablar simplemente de "Herencia múltiple" en general, sin detalles específicos. Así que supondré que te refieres a "herencia múltiple C++" cuando dices "herencia múltiple".

El problema más común con la herencia múltiple es el Diamond Problem. Si varias superclases en el mismo nivel definen el mismo método, ¿cómo sabe qué método se invoca en la subclase?

Con los módulos, este problema se responde fácilmente: el último módulo incluido siempre "gana". No puede incluir varios módulos "simultáneamente", como puede hacer con las clases en C++. Entonces este problema nunca surge.

El hecho de que no se puede crear una instancia de un módulo es irrelevante cuando se utiliza como una superclase

respetuosamente en desacuerdo.

Primero, los módulos nunca se "usan como superclases" en ruby; solo las superclases son

En segundo lugar, con la herencia múltiple, saber exactamente en qué orden se llaman los constructores (& destructores) es not a trivial matter. El hecho de que los módulos ruby ​​no permitan la creación de instancias elimina por completo ese problema.

+1

Gracias, sin embargo, una mejor comparación sería el MI de Python, en lugar de C++. Yo, respetuosamente estoy en desacuerdo con respecto a los módulos incluidos y 'superclases' :). Un módulo incluido funciona casi exactamente como lo hace una 'superclase' en Ruby: ese es el puntero de la superclase de los puntos de clase para el módulo incluido (del mismo modo que apuntaría a la superclase). Además, el hecho de que los módulos de Ruby sigan la regla "el último módulo incluido siempre" gana "" podría verse simplemente como un algoritmo de linealización, similar a la linealización c3 de Pythons, por lo que no veo cómo esto lo diferencia de MI. – horseyguy

+0

"casi" no es lo mismo que "exactamente". Las diferencias son importantes Por ejemplo, 'super' no funciona para módulos. Pero en cualquier caso, no me di cuenta de que esta era una pregunta de Python. Supongo que merezco el -1:/ – kikito

+1

super no funciona para los módulos? si lo hace – horseyguy