Estendendo Objetos
Parte da seção Programação orientada a objetos do Journey de Ruby da Coddy. Lição 28 de 57.
extend adiciona os métodos de um módulo a um objeto, em vez de a todas as instâncias. Estender uma classe os adiciona ao objeto da classe, fazendo com que se tornem métodos de classe:
module Describable
def describe
"#{name} has #{instance_methods(false).size} methods"
end
end
class Dog
extend Describable
def bark
"Woof"
end
def sit
"sits"
end
end
puts Dog.describeSaída:
Dog has 2 methodsUm módulo usado com extend pode manter o estado em variáveis de instância da classe. Cada classe que o estende obtém sua própria cópia, como variáveis de instância da classe:
module Counted
def created
@created ||= 0
end
def record
@created = created + 1
end
end
class Order
extend Counted
end
class Invoice
extend Counted
end
Order.record
Order.record
Invoice.record
puts "#{Order.created} #{Invoice.created}"Saída:
2 1extend também funciona em um único objeto. Somente esse objeto obtém os métodos; outras instâncias de sua classe permanecem inalteradas, e is_a? é true apenas para o objeto estendido:
module Shiny
def polish
"#{self} is shining"
end
end
a = "car"
b = "bike"
a.extend(Shiny)
puts a.polish
puts a.is_a?(Shiny)
puts b.respond_to?(:polish)Saída:
car is shining
true
falseAs duas palavras-chave colocam os métodos do mesmo módulo em lugares diferentes. include os transforma em métodos de instância de uma classe, enquanto extend os transforma em métodos do único objeto que é estendido:
class Order
include Printable # order.print_me (cada instância)
extend Counted # Order.record (a própria classe)
end
item.extend(Shiny) # item.polish (apenas este objeto)Desafio
FácilComplete o módulo Registry, que as classes usam com extend. register(name) adiciona um nome à própria lista da classe, mantida em @entries (criada no primeiro uso), e retorna Plugin registered x; um nome que já esteja nela retorna Plugin already has x. entries retorna a lista, e count, seu tamanho. Tanto Plugin quanto Theme estendem Registry e mantêm listas separadas.
O código fornecido lê linhas plugin name ou theme name, chama register na classe correspondente e imprime a resposta. Por fim, imprime plugins: a, b (2) e themes: ..., ou none (0) para uma lista vazia.
Seu código deve ficar em registry.rb, plugin.rb e theme.rb. main.rb contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
require_relative 'registry'
require_relative 'plugin'
require_relative 'theme'
# Código de entrada/saída fornecido: mantenha-o como está
input = []
while (line = gets)
input << line.chomp
end
input.each do |line|
kind, name = line.split
target = kind == "plugin" ? Plugin : Theme
puts target.register(name)
end
[["plugins", Plugin], ["themes", Theme]].each do |label, klass|
list = klass.entries.empty? ? "none" : klass.entries.join(", ")
puts "#{label}: #{list} (#{klass.count})"
end
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação orientada a objetos
1Classes e Objetos
Trabalhando com ArquivosDefinindo ClassesVariáveis de InstânciaMétodos e selfto_s e inspectRevisão - Cartão da Biblioteca4Encapsulamento
Métodos privadosMétodos protegidosSetters privadosProtegendo o estadoRevisão - Máquina de venda automática7Polimorfismo e Duck Typing
PolimorfismoDuck TypingMétodos Abstratoscase e ClassesRevisão - Métodos de Pagamento2Acessores e self
Leitores e GravadoresSetters Personalizadosself nos MétodosIdentidade e IgualdadeRecapitulação - Lista de Contatos5Herança
SubclassesSobrescrita de métodosChamando superis_a? e ancestraisRevisão - Folha de pagamento da equipe8Métodos Especiais
Igualdade e hashMétodos de OperadoresIndexação e AdiçãoColeções PersonalizadasRevisão - Frações11Projeto: Gerenciamento de Biblioteca
Livros e MembrosEmpréstimo de Livros3Métodos e Variáveis de Classe
Métodos de ClasseVariáveis de Instância da ClasseConstantesMétodos de FábricaRevisão - Códigos de Cupom6Módulos e Mixins
Módulos e includeEstendendo ObjetosO Módulo ComparableO Módulo EnumerableRecapitulação - Liga EsportivaPratique por conta própria: Compilador de Ruby online