Pergunta

Eu vim de Java, e agora eu estou trabalhando mais com Ruby.

Uma característica língua que eu não estou familiarizado com o module. Eu estou querendo saber o que exatamente é um module e quando você usar um, e por que usar um module sobre um class?

Foi útil?

Solução

A primeira resposta é boa e dá algumas respostas estruturais, mas uma outra abordagem é pensar sobre o que você está fazendo. Os módulos são sobre o fornecimento de métodos que podem ser usados ??em diversas classes - pensar sobre eles como "bibliotecas" (como você veria em um aplicativo de Rails). As classes são cerca de objectos; módulos são sobre funções.

Por exemplo, sistemas de autenticação e autorização são bons exemplos de módulos. sistemas de autenticação de trabalhar em várias classes de nível aplicativo (usuários são autenticados, sessões de gerenciar a autenticação, os lotes de outras classes vão agir de forma diferente com base no estado auth), de modo que os sistemas de autenticação agir como APIs compartilhadas.

Você também pode usar um módulo quando você tem métodos em vários aplicativos compartilhados (mais uma vez, o modelo de biblioteca é bom aqui).

Outras dicas

╔═══════════════╦═══════════════════════════╦═════════════════════════════════╗
║               ║ 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)          ║
╚═══════════════╩═══════════════════════════╩═════════════════════════════════╝

Estou ninguém surpreso se não disse isso ainda.

Uma vez que o autor da questão veio de um fundo Java (e eu também), aqui está uma analogia que ajuda.

As aulas são simplesmente como classes Java.

Os módulos são como classes estáticas de Java. Pense em classe Math em Java. Você não instanciá-lo, e você reutilizar os métodos na classe estática (eg. Math.random()).

Basicamente, o módulo não pode ser instanciado. Quando uma classe inclui um módulo, uma superclasse proxy é gerado que fornece acesso a todos os métodos do módulo, bem como os métodos de classe.

Um módulo pode ser incluído por várias classes. Módulos não pode ser herdada, mas este modelo "mixin" fornece um tipo útil de "inheritrance múltipla". puristas OO vai discordar com essa afirmação, mas não deixe pureza ficar no caminho de fazer o trabalho.


(Esta resposta originalmente ligada à http://www.rubycentral.com/pickaxe/classes.html, mas esse link e seu domínio não estão mais ativas.)

Module em Ruby, até certo ponto, corresponde a Java classe abstrata - tem métodos de instância, as classes podem herdar a partir dele (via include, Ruby caras chamam de "mixin"), mas tem nenhum dos casos. Há outras pequenas diferenças, mas esta quantidade de informação é o suficiente para você começar.

namespace: módulos são namespaces ... que não existem em java;)

Eu também mudou de Java e Python para Ruby, eu me lembro tinha exatamente essa mesma pergunta ...

Portanto, a resposta mais simples é que o módulo é um espaço de nomes, o que não existe em Java. Em java a mentalidade mais próximo namespace é um pacote .

Assim, um módulo em Ruby é como o que em java:
classe? Não
interface? Não
classe abstrata? Não
pacote? Sim (talvez)

métodos estáticos dentro de classes em java: o mesmo que métodos dentro módulos em ruby ??

Em java a unidade mínima é uma classe, você não pode ter uma função fora de uma classe. No entanto, em ruby ??isso é possível (como python).

Então, o que se passa em um módulo?
classes, os métodos constantes. Módulo protege-los sob esse namespace.

Nenhuma instância: módulos não pode ser usado para criar instâncias

ins mistos: , por vezes, herança modelos não são bons para aulas, mas em termos de funcionalidade pretende agrupar um conjunto de classes / métodos / constantes juntos

Regras sobre módulos em Ruby:
- Módulo nomes são UpperCamelCase
- constantes dentro de módulos são todos os CAPS (esta regra é a mesma para todas as constantes rubi, não é específico para módulos)
- métodos de acesso: o uso. operador
- constantes de acesso: uso :: símbolo

exemplo simples de um módulo:

module MySampleModule
  CONST1 = "some constant"

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

como usar os métodos dentro de um módulo:

puts MySampleModule.method_one(1) # prints: 3

Como usar constantes de um módulo:

puts MySampleModule::CONST1 # prints: some constant

Algumas outras convenções sobre módulos:
Use um módulo em um arquivo (como aulas de rubi, uma classe por arquivo rubi)

Linha inferior:. Um módulo é um cruzamento entre uma classe estático / utilidade e um mixin

Mixins são peças reutilizáveis ??de implementação "parcial", que podem ser combinados (ou compostas) em um mix & match moda, para ajudar a escrever novas classes. Essas classes podem também ter seu próprio Estado e / ou de código, é claro.

Class

Quando você define uma classe, você define um modelo para um tipo de dados. dados de classe espera, tem método que interagem com esses dados e são usados ??para objetos instanciar.

módulo

  • Os módulos são uma forma de agrupar métodos em conjunto, classes e constantes.

  • Módulos dar-lhe duas grandes vantagens:

    => módulos fornecem um espaço de nomes e evitar conflitos de nome. Namespace ajuda conflitos evitar com funções e classes com o mesmo nome que ter sido escrito por outra pessoa.

    => Módulos implementar a instalação mixin.

(incluindo módulo em Klazz dá exemplos de acesso Klazz ao Módulo métodos. )

(estender Klazz com Mod dando a classe de acesso Klazz aos métodos Mods.)

Em primeiro lugar, algumas semelhanças que não foram mencionados ainda. Rubi suporta aulas abertas, mas módulos tão aberto também. Afinal, herda Classe do Módulo na cadeia Classe herança e assim Classe e Módulo têm um comportamento similar.

Mas você precisa se perguntar qual é o propósito de ter tanto uma classe e um módulo em uma linguagem de programação? Uma classe destina-se a ser um modelo para criar casos, e cada instância é uma variação realizada do modelo. Um exemplo é simplesmente uma variação realizado de uma planta (a classe). Naturalmente, em seguida, Classes de funcionar como a criação do objecto. Além disso, uma vez que, por vezes, quer um plano para derivar de outro modelo, classes são projetadas para herança apoio.

Os módulos não pode ser instanciado, não criam objetos, e não suportam herança. Então lembre-se de um módulo não herdar de outra!

Então, o que é o ponto de ter módulos em um idioma? Um uso óbvio de Módulos é criar um espaço de nomes, e você vai notar isso com outras línguas também. Novamente, o que é legal sobre Ruby é que os módulos podem ser reabertos (assim como Classes). E este é um grande uso quando quiser reutilizar um espaço de nomes em diferentes arquivos 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

Mas não há nenhuma herança entre os 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>

O módulo da Apple não herdam os métodos do módulo verde e quando incluída a Apple na classe Fruit, os métodos do módulo da Apple são adicionados à cadeia ancestral de instâncias da Apple, mas não os métodos do módulo verde, mesmo embora o módulo verde foi definido no módulo Apple.

Então, como podemos ter acesso ao método de verde? Você tem que incluir explicitamente na sua classe:

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

Mas Ruby tem outro uso importante para os módulos. Esta é a instalação Mixin, que descrevo em outra resposta no SO. Mas, para resumir, mixins permitem definir métodos para a cadeia de herança de objetos. Através mixins, você pode adicionar métodos para a cadeia de herança de instâncias de objetos (incluir) ou o singleton_class de auto (estender).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top