O que acontece quando um método não existe
Um erro conhecido, visto de perto
NoMethodError apareceu muitas vezes nesta série: um erro de digitação, um método chamado no tipo errado, um nome que não existe naquele objeto.
"hello".fly
# levanta: NoMethodError: undefined method 'fly' for an instance of String
O instinto é ler isso como "o Ruby checou, fly não existe, erro". Está perto, mas pula um passo, e este curso, o último dos nove desta série, se apoia nesse passo.
O Ruby não desiste na hora
Antes de levantar NoMethodError, o Ruby sobe pela cadeia de ancestors do objeto procurando um método chamado fly: a classe dele, a superclasse dessa classe, os módulos incluídos, até o topo. Só quando essa busca volta vazia o Ruby dá mais um passo. Ele chama um método chamado method_missing no objeto, passando o nome tentado, :fly, junto com os argumentos e o bloco da chamada original. String não sobrescreve method_missing, então roda a versão padrão, definida em BasicObject, cujo trabalho é levantar NoMethodError. É esse o erro que todos os cursos anteriores mostraram. Ele nunca foi um caso especial; era o comportamento padrão do method_missing.
Por que isso importa: dá para sobrescrever o gancho
method_missing é um método comum, definido em BasicObject e herdado por todo objeto Ruby, então qualquer classe pode sobrescrevê-lo como qualquer outro método. Sobrescrever é entrar nesse momento, logo antes de o Ruby levantar NoMethodError, e decidir que outra coisa deve acontecer.
class Ghost
def method_missing(name, *args)
"you called #{name} with #{args.inspect}, and nothing by that name exists, but I intercepted it"
end
end
Ghost.new.anything_at_all(1, 2)
# => "you called anything_at_all with [1, 2], and nothing by that name exists, but I intercepted it"
anything_at_all nunca foi definido. Chamá-lo não levanta erro, porque o method_missing do próprio Ghost pegou a chamada antes de o padrão do Ruby rodar.
O que este curso cobre
- Sobrescrever
method_missingpara tratar chamadas a métodos que nunca foram definidos. respond_to_missing?, o método que você precisa sobrescrever junto, e por que pulá-lo é um erro comum.- Chamar
superdentro domethod_missingpara tudo o que você não trata, para que um erro de digitação ainda levanteNoMethodErrorem vez de ser absorvido. - Como isso fecha a série de nove cursos de OOP em Ruby, das classes até este mecanismo, e o que vem depois.
Pontos-chave
- Antes de levantar
NoMethodError, o Ruby chamamethod_missingno objeto, passando o nome do método tentado, os argumentos e o bloco. - O
NoMethodErrorvisto ao longo desta série era omethod_missingpadrão deBasicObjectrodando, e não um caminho de erro separado. - Como
method_missingé um método comum e herdado, qualquer classe pode sobrescrevê-lo para pegar chamadas a métodos que não existem. - Este curso trata de fazer essa sobrescrita de forma correta e segura, e fecha a série de nove cursos de OOP em Ruby.
Continue com a aula 2
Sobrescrevendo method_missing
A assinatura do method_missing e uma sobrescrita que responde a uma família de chamadas, como x, y e z.
Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.