Carlos Brando

Nome do Jogo

Classes são Módulos no Ruby

Qual é a diferença entre uma classe e um módulo no Ruby? Nenhuma, uma classe é um módulo no Ruby. Não acredita em mim?

1
Class.is_a?(Module) # => true

Agora que você já confia em mim, posso explicar com um pouco mais de calma.

O que são módulos?

Um módulo pode ser definido de forma grosseira como uma coleção de métodos e constantes. Você encontrará dois tipos de métodos em um módulo: métodos de instância e métodos de módulo. Um método de módulo é aquele que pode ser executado sem a necessidade de que o módulo seja incluído em outro objeto:

1
2
3
4
5
6
7
module MeuModulo
  def self.meu_metodo_de_modulo
    puts "Sou um m茅todo de m贸dulo!"
  end
end

MeuModulo.meu_metodo_de_modulo # => Sou um m茅todo de m贸dulo!

Por outro lado, métodos de instância, como o nome diz, precisam ser executados a partir de uma instância de um objeto. Módulos podem ser acoplados dentro de outros objetos, tornando assim estes métodos de instância acessíveis.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module MeuModulo
  def meu_metodo_de_intancia
    puts "Método de instância!"
  end
end

class MinhaClasse
  # Acoplando o MeuModulo
  include MeuModulo
end

# Criando uma instância de MinhaClasse
minha_classe = MinhaClasse.new

# Executando o método de instância que foi criado em MeuModulo
puts minha_classe.meu_metodo_de_intancia # => Método de instância!

O que são classes?

Assim como os módulos, classes também são repositórios de métodos. Então qual é a diferença entre um e o outro?

Podemos ver claramente a diferença entre classes e módulos examinando o objeto Class mais de perto:

1
2
3
4
Class.superclass # => Module

Class.instance_methods(false)
# => ["superclass", "allocate", "new", "to_yaml"]

Como você pode ver no código acima, Class é uma subclasse de Module, mas com quatro métodos a mais. E é exatamente nestes métodos que encontraremos a resposta para a questão levantada acima.

Para esclarecer ainda mais, vamos imaginar como seria a classe Class implementada em Ruby:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Class < Module
  # Você já sabe como funciona o método new,
  # já que o utilizamos o tempo todo
  def initialize
  end

  # Devolve a superclasse da classe atual
  def superclass
  end

  # Dá suporte ao método new
  def allocate
  end

  def to_yaml
  end
end

Os três primeiros métodos são responsáveis por permitir que você consiga criar uma instância de um objeto e trabalhar com o conceito de hierarquia de classes. O método to_yaml serve apenas como uma interface que dispara um erro do tipo TypeError caso ele não seja implementado por uma subclasse.

O método superclass é fácil de entender, já que a sua única finalidade é informar qual é a superclasse de um objeto. Se uma superclasse não for definida ele retornará nil.

1
2
Integer.superclass # => Numeric
Object.superclass # => nil

O método allocate é responsável por reservar um espaço na memória para a nova instância do objeto que estamos criando. O método devolve esta instância pronta.

E por último, o método initialize (new) tem duas funções. Primeiro ele executa o método allocate, que constrói um novo objeto da classe Class (ou de qualquer outra classe, afinal todas elas são subclasses de Class). Em seguida ele dispara o método initialize deste objeto, passando os argumentos para ele.

Finalizando

Se você chegou até aqui, então já entendeu as diferenças entre um módulo e uma classe em Ruby. Basta pensar que ambos são basicamente a mesma coisa (com estas significantes diferenças) e que quase tudo o que vale para um também vale para o outro.

A principal razão de existir estes dois tipos de objetos tão parecidos e ao mesmo tempo tão diferentes é que desta forma podemos deixar nosso código muito mais expressivo.

Normalmente você usará um módulo quando precisar incluí-lo em outro objeto ou usá-lo como um namespace. E você usará uma classe quando precisar de uma instância de um objeto ou utilizar o sistema de heranças. Cada um tem o seu propósito e você será melhor sucedido se utilizar o recurso certo na hora certa.


Este artigo é o primeiro de muitos com a finalidade de explicar como o Ruby e Rails funcionam por dentro, conforme prometido durante a minha palestra no Rails Summit.

Comments