O Método “Extend” e Seus Usos

Provavelmente muita gente conhece o método “extend”, usado principalmente em classes para adicionar métodos, tais como:

module Nameable
  def set_name(name)
    @name = name
  end
end

class MyClass
  extend Nameable
  set_name "Foo Bar"
end

Claro que há pessoas que fazem verdadeiras aberrações, tipo um “module” que define o callback “included” que chama um “extend”, tipo essa situação:

module Nameable
  def self.included(klass)
    klass.extend Nameable::ClassMethods
  end

  module ClassMethods
    def set_name(name)
      @name = name
    end
  end
end

class MyClass
  include Nameable
  set_name "Foo Bar"
end

Mas vamos ignorar esse tipo de coisa e pensar em outras formas de usar o “extend”. Digamos que temos uma classe como a seguir:

class Authenticator
  def login(username, password)
    if User.find_by_username_and_password(username, password)
      return true
    else
      return false
    end
  end

Ok, temos uma regra para autenticar (aviso: não use isso em produção, o código prevê que os usuários tem suas senhas gravadas no banco sem criptografia nenhuma). Digamos, agora, que em um determinado cliente, esse código só não é o suficiente: o cliente quer que, antes de autenticar no banco, se autentique no sistema

Uma solução é usar monkey-patch. Nesse caso, teríamos um código em outro lugar que redefiniria a classe e adicionaria novos métodos, tipo:
(more…)