O sistema de módulos do Ruby é uma ferramenta poderosa para organização e reutilização de código. Dois métodos-chave, include
e extend
, permitem incorporar funcionalidades de módulos em classes, mas o fazem de maneiras fundamentalmente diferentes. Este artigo esclarece suas distinções e o guia na escolha do método apropriado para suas necessidades.
Sumário
Entendendo include
em Ruby
O método include
traz os métodos de um módulo para as instâncias de uma classe. Cada objeto criado a partir da classe herdará e poderá utilizar esses métodos.
module Sayable
def speak(message)
puts message
end
end
class Dog
include Sayable
end
sparky = Dog.new
sparky.speak("Woof!") # => Woof!
Neste exemplo, as instâncias de Dog
, como sparky
, ganham o método speak
por causa de include
.
Entendendo extend
em Ruby
extend
, inversamente, adiciona os métodos de um módulo diretamente à própria classe, não às suas instâncias. Esses métodos são chamados na classe, mas não em objetos individuais criados a partir dessa classe.
module Growlable
def growl
puts "Grrrr!"
end
end
class Cat
extend Growlable
end
Cat.growl # => Grrrr!
whiskers = Cat.new
# whiskers.growl # => NoMethodError: undefined method 'growl' for #<Cat:0x...>
Apenas a classe Cat
pode chamar growl
; whiskers
, uma instância de Cat
, não pode.
Quando Usar include
vs. extend
A decisão depende inteiramente se você precisa de métodos acessíveis no nível de instância ou no nível de classe.
- Use
include
quando: Você está adicionando métodos que devem estar disponíveis para cada objeto (instância) da classe. Este é o caso de uso mais comum. Pense em adicionar comportamentos ou funcionalidades a objetos individuais. - Use
extend
quando: Você está adicionando métodos que operam na própria classe, como métodos de nível de classe (por exemplo, métodos de fábrica) ou métodos que modificam o comportamento da classe. Esses métodos geralmente não requerem acesso a variáveis de instância.
Conclusão
include
e extend
são ambas ferramentas valiosas no arsenal do Ruby. Entender seus comportamentos distintos — métodos de nível de instância versus métodos de nível de classe — é crucial para escrever código limpo, manutenível e eficiente. Escolher a abordagem certa impacta significativamente o design e a legibilidade do código.
FAQ
- Posso
extend
múltiplos módulos? Sim, estender múltiplos módulos adiciona seus métodos à classe. - Posso
include
eextend
o mesmo módulo? Sim, fornecendo métodos de nível de instância e de classe a partir desse módulo. - O que acontece se os módulos definirem métodos com o mesmo nome? O último módulo incluído ou estendido vence; seu método substitui os outros (substituição de método).
- Há implicações de desempenho? As diferenças de desempenho são geralmente insignificantes. Priorize o design do código sobre pequenas otimizações de desempenho.