Pergunta

method_missing

* obj.method_missing (símbolo h, args i) ? other_obj

Chamado por Ruby quando obj é enviado um Mensagem não pode manipular. símbolo é o símbolo para o método chamado, e args são quaisquer argumentos que eram passado para ele. O exemplo abaixo cria um romano de classe, que responde a métodos com nomes consistindo de algarismos romanos, retornando o valores inteiros correspondente. A mais uso típico de method_missing é implementar proxies, delegante, e forwarders.

class Roman
  def roman_to_int(str)
    # ...
  end
  def method_missing(method_id)
    str = method_id.id2name
    roman_to_int(str)
  end
end
r = Roman.new
r.iv ! 4
r.xxiii ! 23
r.mm ! 2000

Acabei de ouvir sobre o método-falta e foi para saber mais no Programação rubi , mas a explicação acima citado do livro é sobre a minha cabeça. Alguém tem uma explicação mais fácil? Mais especificamente, é utilizado pelo intérprete faltando-método ou há sempre uma necessidade de chamá-lo diretamente em um programa (supondo que eu só estou escrevendo aplicações web, em vez de escrever código para NASA)?

Foi útil?

Solução

Ruby não têm qualquer aplicação tipo, e também não faz qualquer verificação, que métodos um objeto tem quando o script é primeiramente analisados, porque este pode ser alterado dinamicamente como o aplicativo é executado.

O que method_missing faz, é deixá-lo interceptar e identificador de chamadas para métodos que não existem para um determinado objeto. Isto fornece o poder sob o capô atrás de praticamente todos os DSL (linguagem específica de domínio) escrito em Ruby.

No caso do exemplo, cada um dos 'r.iv', 'r.mm', e assim por diante é realmente uma chamada de método para o objeto Roman. Claro, ele não tem um 'iv' ou um método de 'mm', então ao invés de controle é passado para method_missing, que recebe o nome do método que foi chamado, assim como tudo o que argumentos foram passados.

method_missing em seguida, converte o nome do método a partir de um símbolo para uma cadeia, e analisa-lo como um número romano, retornando a saída como um inteiro.

Outras dicas

É provavelmente melhor não pensar em ruby ??como tendo métodos. Quando você chama um rubi "método" na verdade você está enviando uma mensagem para essa instância (ou classe) e se você tiver definido um manipulador para a mensagem, ele é usado para processo e retornar um valor.

Assim method_missing é uma definição especial que é chamado sempre que Ruby não pode encontrar um manipulador de apropriate. Você também pode pensar nisso como um método *.

É basicamente um catch-all para mensagens que não correspondem a quaisquer métodos. É usado extensivamente em registro ativo para finders dinâmicos. É o que permite que você escrever algo como isto:

SomeModel.find_by_name_and_number(a_name, a_number)

O modelo não contém código para que find_by, então method_missing é chamado que analisa é diz - Eu reconheço esse formato, e leva-lo para fora. Se isso não acontecer, então você obtém um método não encontrou o erro.

No exemplo Roman você fornecê-lo ilustra como você pode estender a funcionalidade de uma classe sem definir explicitamente métodos.

r.iv não é um método tão capturas method_missing TI e chamadas roman_to_int no id método de "iv"

Também é útil quando você deseja manipular métodos não reconhecidos em outros lugares, como proxies, delegante e forwarders, como os estados de documentação.

Você não chamar "method_missing" (o intérprete chama). Em vez disso, você definir ele (substituí-lo) para uma classe que você quer fazer para ser mais flexível. Como mencionado em outros comentários, o intérprete vai chamar a sua versão do method_missing quando a classe (ou instância) não ( "explicitamente"?) Definir o método solicitado. Isso lhe dá uma chance de fazer alguma coisa, com base no método nome ersatz / mensagem.

Você já fez qualquer programação "reflexão" em Java? Usando este método seria como se a classe para ser acessado via reflexão poderia olhar para a string (desculpe-me, "símbolo") do nome do método se uma exceção no-such-método foi lançada, e depois fazer algo como isso é método implementação em tempo real.

A programação dinâmica é uma espécie de "one-up" na reflexão.

Uma vez que você menciona aplicações web eu vou adivinhar que você está familiarizado com Ruby on Rails. Um bom exemplo de como method_missing podem ser usados ??são os diferentes métodos find_by_<whatever> que está disponível. Nenhum desses métodos realmente existe! Eles são sintetizados durante o tempo de execução. Tudo isso mágica acontece por causa de como rubi intercepta invocações de métodos não-existente.

Você pode ler mais sobre isso e outros usos de method_missing aqui .

ActiveRecord usa method_missing definir métodos find_by. Mas uma vez que, method_missing é basicamente um método de último recurso, este pode ser um gargalo de desempenho sério. O que eu descobri é que ActiveRecord faz algum mais metaprogramming incrível, definindo o novo método finder como um método de classe !! Assim, quaisquer chamadas para o mesmo método localizador não teria atingido o method_missing porque agora é um método de classe. Para obter detalhes sobre o código real trecho de base.rb, clique aqui .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top