O que acontece quando um método não existe

Prévia grátis 3 min de leitura

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_missing para 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 super dentro do method_missing para tudo o que você não trata, para que um erro de digitação ainda levante NoMethodError em 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 chama method_missing no objeto, passando o nome do método tentado, os argumentos e o bloco.
  • O NoMethodError visto ao longo desta série era o method_missing padrão de BasicObject rodando, 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.
Aula 1 de 7 · grátis

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.

Digite para buscar...