Hoje vamos continuar falando de Ruby, é hora de continuar nos aprofundando um pouco mais de Reflexão e Metaprogramação agora Hooks... Estranho para alguns, mas, veremos que é simples!
Hooks
Class
, Module
, e os vários métodos de retorno da chamada do Objectimplement
, ou hooks
. Estes métodos não são definidos por padrão, mas se você
defini-los para um módulo de classe, ou objeto, então eles vão ser invocados quando ocorrerem determinados eventos. Isso lhe dá uma oportunidade para
estender o comportamento de Ruby quando as classes são uma subclasse, quando os módulos estão incluídos, ou quando os métodos são definidos. Métodos de
hook
(exceto para alguns mais preteridos não descritos aqui) têm nomes que terminam em “ed”.
Quando uma nova classe é definida, Ruby chama o método de classe herdada na superclasse da nova classe, passando o objeto da nova classe como
argumento. Isso permite adicionar classes para comportamento ou impor restrições sobre seus descendentes. Lembre-se que os método de classe são
herdados, de modo que a um método herdado será chamado se ele é definido por qualquer um dos antepassados da nova classe. Definir Object.inherited
para receber a notificação de todas as novas classes que são definidas:
1 2 3 |
|
Quando um módulo é incluído numa classe ou em outro módulo, o método da classe incluída do módulo incluído é chamado com o objeto de classe ou módulo em que foi incluído como um argumento. Isto dá o módulo incluído uma oportunidade para aumentar ou alterar a classe da maneira que ele efetivamente quer ser permitido que um módulo define o seu próprio significado para incluir. Além da adição de métodos para a classe em que se insere, um módulo com um método incluído também que pode alterar os métodos existentes dessa classe, por exemplo:
1 2 3 4 5 6 7 8 9 10 |
|
Da mesma forma, se um módulo de classe define um método chamado extended
, este método será invocado em qualquer momento que o módulo é utilizado para
estender um objeto (com Object.extend
). O argumento para o método de extensão será o objeto que foi estendido, é claro, e do método estendido pode
tomar quaisquer ações que quer o objeto.
Além de hooks
para rastreiar as classes e os módulos que incluem, também existem hooks
para rastrear os métodos de classes e módulos e os únicos
métodos de objetos arbitrários. Defini um método de classe chamado method_added
para qualquer classe ou módulo e ele será chamado quando um método de
instância é definido para essa classe ou módulo:
1 2 3 |
|
Note-se que o método da classe method_added
é herdado pelas subclasses da classe em que ele está definido. Mas nenhum argumento de classe é passado
para o hook
, pelo que não há maneira de dizer se o método chamado foi adicionado à classe que define method_added
ou se ela foi adicionada a uma
subclasse desta classe. A solução para este problema é definir um hook
que herda em qualquer classe uma definição de um hook
method_added
.
O método pode então ser herdado um método que defini method_added
para cada subclasse.
Quando um método singleton
é definido para qualquer objeto, o método singleton_method_added
é invocado sobre o objeto, passando o nome do novo
método. Lembre-se que para as classes, métodos singleton
são métodos de classe:
1 2 3 |
|
Curiosamente, Ruby invoca esse hook
singleton_method_added
quando o método de hook
em si é definido previamente. Aqui é um outro uso do hook
.
Neste caso, singleton_method_added
é definido como um método de instância de uma classe que inclui um módulo. É notificado de qualquer métodos
singleton
adicionados a instâncias da classe:
1 2 3 4 5 6 7 8 9 10 |
|
Além de method_added
e singleton_method_added
, há hook
para rastreamento quando os métodos de instância e métodos singleton
são removidos ou
indefinidos. Quando um método de instância é removido ou indefinido em uma classe ou módulo, os métodos de classe method_removed
e method_undefined
são invocados nesse módulo. Quando um método singleton
é removido ou indefinido em um objeto, os métodos singleton_method_removed
e
singleton_method_undefined
são invocados nesse objeto.
Por fim, note que os métodos method_missing
e const_missing
também se comportam como métodos de hook
.
Até o proximos amigos!