metodo - ruby variável de classe




Diferença entre uma classe e um módulo (6)

Eu vim do Java e agora estou trabalhando mais com o Ruby.

Um recurso de idioma que não conheço é o module . Eu estou querendo saber o que exatamente é um module e quando você usa um, e por que usar um module sobre uma class ?


A primeira resposta é boa e dá algumas respostas estruturais, mas outra abordagem é pensar sobre o que você está fazendo. Os módulos são sobre fornecer métodos que você pode usar em várias classes - pense neles como "bibliotecas" (como você veria em um aplicativo Rails). Classes são sobre objetos; módulos são sobre funções.

Por exemplo, sistemas de autenticação e autorização são bons exemplos de módulos. Os sistemas de autenticação funcionam em várias classes no nível do aplicativo (os usuários são autenticados, as sessões gerenciam a autenticação, muitas outras classes agirão de maneira diferente com base no estado de autenticação), portanto os sistemas de autenticação atuam como APIs compartilhadas.

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


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

Um módulo pode ser incluído por várias classes. Os módulos não podem ser herdados, mas esse modelo "mixin" fornece um tipo útil de "herdabilidade múltipla". Os puristas da OO não concordarão com essa afirmação, mas não deixem que a pureza atrapalhe o trabalho.

(Essa resposta foi originalmente vinculada a http://www.rubycentral.com/pickaxe/classes.html , mas esse link e seu domínio não estão mais ativos.)


Estou surpreso que alguém não tenha dito isso ainda.

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

Classes são simplesmente como classes Java.

Módulos são como classes estáticas de Java. Pense na aula de Math em Java. Você não o instancia, e reutiliza os métodos na classe estática (por exemplo, Math.random() ).


Primeiro, algumas semelhanças que ainda não foram mencionadas. Ruby suporta classes abertas, mas os módulos também são abertos. Afinal de contas, Class herda de Module na cadeia de herança de Classes e, portanto, Classe e Módulo têm um comportamento similar.

Mas você precisa se perguntar qual é o propósito de ter uma Classe e um Módulo em uma linguagem de programação? Uma classe destina-se a ser um blueprint para criar instâncias e cada instância é uma variação realizada do blueprint. Uma instância é apenas uma variação realizada de um blueprint (a classe). Naturalmente, as Classes funcionam como criação de objetos. Além disso, como às vezes queremos que um modelo seja derivado de outro blueprint, as Classes são projetadas para dar suporte à herança.

Módulos não podem ser instanciados, não criam objetos e não suportam herança. Então lembre-se de um módulo não herda de outro!

Então, qual é o sentido de ter módulos em uma linguagem? Um uso óbvio dos módulos é criar um espaço para nome e você perceberá isso com outros idiomas também. Novamente, o que é legal sobre o Ruby é que os módulos podem ser reabertos (assim como as classes). E isso é um grande uso quando você deseja reutilizar um namespace 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á 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 Apple não herdou nenhum método do módulo Green e, quando incluímos a Apple na classe Fruit, os métodos do módulo Apple são adicionados à cadeia ancestral das instâncias da Apple, mas não aos métodos do módulo Green, embora o Green módulo foi definido no módulo Apple.

Então, como podemos obter acesso ao método verde? Você precisa incluí-lo explicitamente em sua turma:

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

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


Module em Ruby, até certo ponto, corresponde à classe abstrata Java - tem métodos de instância, classes podem herdar dele (via include , caras Ruby chamam de "mixin"), mas não tem instâncias. Existem outras pequenas diferenças, mas essa informação é suficiente para você começar.


Classe

Quando você define uma classe, você define um blueprint para um tipo de dados. class hold data, tem métodos que interagem com esses dados e são usados ​​para instanciar objetos.

Módulo

  • Módulos são uma maneira de agrupar métodos, classes e constantes.

  • Os módulos oferecem dois grandes benefícios:

    => Os módulos fornecem um namespace e evitam confrontos de nomes. Namespace ajuda a evitar conflitos com funções e classes com o mesmo nome que foram escritas por outra pessoa.

    => Módulos implementam o mixin facility.

(Incluindo módulo no Klazz dá instâncias de Klazz acesso aos métodos do módulo.)

(estenda o Klazz com Mod, dando à classe Klazz acesso aos métodos Mods.)





module