Pregunta

Vengo de Java, y ahora estoy trabajando más con Ruby.

Una característica de idioma con la que no estoy familiarizado es el module . Me pregunto qué es exactamente un módulo y cuándo usa uno, y por qué usar un module sobre una class ?

¿Fue útil?

Solución

La primera respuesta es buena y ofrece algunas respuestas estructurales, pero otro enfoque es pensar en lo que está haciendo. Los módulos consisten en proporcionar métodos que puede utilizar en varias clases; piense en ellos como "bibliotecas". (como verías en una aplicación Rails). Las clases son sobre objetos; los módulos son sobre funciones.

Por ejemplo, los sistemas de autenticación y autorización son buenos ejemplos de módulos. Los sistemas de autenticación funcionan en varias clases de nivel de aplicación (los usuarios se autentican, las sesiones administran la autenticación, muchas otras clases actuarán de manera diferente según el estado de autenticación), por lo que los sistemas de autenticación actúan como API compartidas.

También puede usar un módulo cuando ha compartido métodos entre múltiples aplicaciones (nuevamente, el modelo de biblioteca es bueno aquí).

Otros consejos

╔═══════════════╦═══════════════════════════╦═════════════════════════════════╗
║               ║ class                     ║ module                          ║
╠═══════════════╬═══════════════════════════╬═════════════════════════════════╣
║ instantiation ║ can be instantiated       ║ can *not* be instantiated       ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ usage         ║ object creation           ║ mixin facility. provide         ║
║               ║                           ║   a namespace.                  ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ superclass    ║ module                    ║ object                          ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ methods       ║ class methods and         ║ module methods and              ║
║               ║   instance methods        ║   instance methods              ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inheritance   ║ inherits behaviour and can║ No inheritance                  ║
║               ║   be base for inheritance ║                                 ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inclusion     ║ cannot be included        ║ can be included in classes and  ║
║               ║                           ║   modules by using the include  ║
║               ║                           ║   command (includes all         ║
║               ║                           ║   instance methods as instance  ║
║               ║                           ║   methods in a class/module)    ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ extension     ║ can not extend with       ║ module can extend instance by   ║
║               ║   extend command          ║   using extend command (extends ║
║               ║   (only with inheritance) ║   given instance with singleton ║
║               ║                           ║   methods from module)          ║
╚═══════════════╩═══════════════════════════╩═════════════════════════════════╝

Me sorprende que nadie haya dicho esto todavía.

Dado que el autor de la pregunta proviene de un fondo de Java (y yo también), aquí hay una analogía que ayuda.

Las clases son simplemente como clases de Java.

Los módulos son como las clases estáticas de Java. Piense en la clase Math en Java. No lo instancia y reutiliza los métodos en la clase estática (por ejemplo, Math.random () ).

Básicamente, el módulo no puede ser instanciado. Cuando una clase incluye un módulo, se genera una superclase de proxy que proporciona acceso a todos los métodos del módulo, así como a los métodos de la clase.

Un módulo puede ser incluido por múltiples clases. Los módulos no se pueden heredar, pero esto "mixin" El modelo proporciona un tipo útil de "herencia múltiple". OO puristas no estarán de acuerdo con esa declaración, pero no dejes que la pureza se interponga en el camino para hacer el trabajo.


(Esta respuesta originalmente estaba vinculada a http://www.rubycentral.com/pickaxe/classes.html , pero ese enlace y su dominio ya no están activos).

Module en Ruby, en cierto grado, corresponde a Java clase abstracta - tiene métodos de instancia, las clases pueden heredar de él (a través de include , Los chicos de Ruby lo llaman "mixin"), pero no tiene instancias. Existen otras diferencias menores, pero esta cantidad de información es suficiente para comenzar.

espacio de nombres: los módulos son espacios de nombres ... que no existen en java;)

También cambié de Java y Python a Ruby, recuerdo que tenía exactamente la misma pregunta ...

Entonces, la respuesta más simple es que el módulo es un espacio de nombres, que no existe en Java. En Java, la mentalidad más cercana al espacio de nombres es un paquete .

Entonces, un módulo en ruby ??es como en Java:
clase? No
interfaz? No
¿clase abstracta? No
paquete? Sí (quizás)

métodos estáticos dentro de clases en java: igual que los métodos dentro de módulos en ruby ??

En java, la unidad mínima es una clase, no puede tener una función fuera de una clase. Sin embargo, en ruby ??esto es posible (como python).

Entonces, ¿qué incluye un módulo?
clases, métodos, constantes. El módulo los protege bajo ese espacio de nombres.

Sin instancia: los módulos no se pueden usar para crear instancias

Entradas mixtas: a veces los modelos de herencia no son buenos para las clases, pero en términos de funcionalidad quieren agrupar un conjunto de clases / métodos / constantes juntos

Reglas sobre módulos en ruby:
- Los nombres de los módulos son UpperCamelCase
- las constantes dentro de los módulos son TODAS MAYÚSCULAS (esta regla es la misma para todas las constantes ruby, no específica para módulos)
- métodos de acceso: uso. operador
- constantes de acceso: use :: symbol

ejemplo simple de un módulo:

module MySampleModule
  CONST1 = "some constant"

  def self.method_one(arg1)
    arg1 + 2
  end
end

cómo usar métodos dentro de un módulo:

puts MySampleModule.method_one(1) # prints: 3

cómo usar las constantes de un módulo:

puts MySampleModule::CONST1 # prints: some constant

Algunas otras convenciones sobre módulos:
Use un módulo en un archivo (como clases de ruby, una clase por archivo de ruby)

Conclusión: un módulo es un cruce entre una clase estática / de utilidad y un mixin.

Las mixinas son piezas reutilizables de "parcial" implementación, que se puede combinar (o componer) en una mezcla & amp; combinar moda, para ayudar a escribir nuevas clases. Estas clases también pueden tener su propio estado y / o código, por supuesto.

Clase

Cuando define una clase, define un plano para un tipo de datos.  datos de retención de clase, tienen un método que interactúa con esos datos y se utilizan para crear instancias de objetos.

Módulo <

  • Los módulos son una forma de agrupar métodos, clases y constantes.

  • Los módulos le brindan dos ventajas principales:

    = > Los módulos proporcionan un espacio de nombres y evitan conflictos de nombres. El espacio de nombres ayuda a evitar conflictos con funciones y clases con el mismo nombre que han sido escritas por otra persona.

    = > Los módulos implementan la instalación mixin.

  

(incluido el Módulo en Klazz proporciona instancias de acceso de Klazz al Módulo   metodos )

     

(extienda Klazz con Mod dando a la clase Klazz acceso a métodos Mods.)

Primero, algunas similitudes que aún no se han mencionado. Ruby admite clases abiertas, pero también módulos abiertos. Después de todo, Class hereda del Módulo en la cadena de herencia de Class y, por lo tanto, Class y Module tienen un comportamiento similar.

¿Pero necesita preguntarse cuál es el propósito de tener una Clase y un Módulo en un lenguaje de programación? Se pretende que una clase sea un modelo para crear instancias, y cada instancia es una variación realizada del modelo. Una instancia es solo una variación realizada de un plano (la Clase). Entonces, naturalmente, las clases funcionan como creación de objetos. Además, dado que a veces queremos que un plano se derive de otro plano, las clases están diseñadas para admitir la herencia.

Los módulos no se pueden crear instancias, no crean objetos y no admiten herencia. ¡Recuerde que un módulo NO hereda de otro!

Entonces, ¿cuál es el punto de tener módulos en un idioma? Un uso obvio de los módulos es crear un espacio de nombres, y también lo notará con otros idiomas. Una vez más, lo bueno de Ruby es que los módulos se pueden volver a abrir (al igual que las clases). Y este es un gran uso cuando desea reutilizar un espacio de nombres en diferentes archivos de Ruby:

module Apple
  def a
    puts 'a'
  end
end

module Apple 
  def b
    puts 'b'
  end
end

class Fruit
  include Apple
end

 > f = Fruit.new
 => #<Fruit:0x007fe90c527c98> 
 > f.a
 => a
 > f.b
 => b

Pero no hay herencia entre módulos:

module Apple
  module Green
    def green
      puts 'green'
    end
  end
end

class Fruit
  include Apple
end

> f = Fruit.new
 => #<Fruit:0x007fe90c462420> 
> f.green
NoMethodError: undefined method `green' for #<Fruit:0x007fe90c462420>

El módulo Apple no heredó ningún método del módulo Verde y cuando incluimos a Apple en la clase Fruit, los métodos del módulo Apple se agregan a la cadena de antecesores de las instancias de Apple, pero no los métodos del módulo Verde, incluso aunque el módulo verde se definió en el módulo de Apple.

Entonces, ¿cómo podemos acceder al método verde? Debe incluirlo explícitamente en su clase:

class Fruit
  include Apple::Green
end
 => Fruit 
 > f.green
=> green

Pero Ruby tiene otro uso importante para los módulos. Esta es la instalación de Mixin, que describo en otra respuesta sobre SO. Pero para resumir, los mixins le permiten definir métodos en la cadena de herencia de los objetos. A través de mixins, puede agregar métodos a la cadena de herencia de instancias de objeto (incluir) o singleton_class of self (extender).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top