Fernando Luizão

Desenvolvimento de software e nerdices em geral

Posts Tagged ‘autoload

Tornando dependências opcionais com autoload

with 2 comments

Uma técnica bacana e que pouca gente conhece é usar o autoload para carregar classes. A função do autoload é a mesma do require (por baixo dos panos, o autoload usa o require), a diferença é que o autoload carregará o arquivo apenas quando for necessário. A idéia é que as constantes sejam registradas e associandas ao arquivo que deve ser requerido, por exemplo:

autoload :MinhaLib, 'minha_lib'

Note que o primeiro argumento é um símbolo, e não a classe. Com módulos é a mesma coisa:

module MeuModulo
  autoload :MinhaLib, 'meu_modulo/minha_lib'
end

Ou ainda:

module MeuModulo
  # coisas do meu modulo
end
MeuModulo.autoload :MinhaLib, 'meu_modulo/minha_lib'

Dessa forma, quando a constante MinhaLib (ou MeuModulo::MinhaLib, no caso do módulo) for usada, o arquivo ‘minha_lib‘ será carregado automaticamente. Qual a utilidade disso? Bem, se a constante não for usada, o arquivo não será carregado, o que nos trás duas vantagens:

  • Como as classes desnecessárias não serão carregadas, a biblioteca será carregada mais rapidamente
  • Conseguimos um mecanismo para tornar dependências opcionais

A primeira vantagem é óbvia, mas a segunda é meio implícita e depende de como o projeto está estruturado.
Por exemplo digamos que temos uma gem, que dependa da gem mail, mas apenas se o usuário desejar notificações. Se declararmos a mail como dependência na gemspec, quando alguém for instalar nossa gem, a mail será instalada mesmo que o usuário não precise dela.

O que podemos fazer para relaxar as dependências é usar o autoload para registrar a constante Mail,
e deixar a cargo do usuário instalar a dependência caso ele precise. Um exemplo de como seria o esqueleto da nossa gem:

# minha_gem.rb
autoload :Mail, 'mail'

# faz o que precisa ser feito

# a gem será carregada apenas se o usuário desejar notificações
# as notificações poderiam ser configuradas por um arquivo *.yml por exemplo
if user_wants_notification?
  Mail.new ...
end

Um exmplo de uso dessa técnica pode ser visto na gem backup, que antes especificava várias dependências na gemspec, e após uma pequena reestruturação, deixaram de ser obrigatórias. Veja aqui como foi feito. Outro exemplo de gem que usa essa técnica é a devise, vale a pena dar uma olhada no código :).

Se você desenvolve alguma gem que usa adaptadores, e esses adaptadores dependem de outras gems, você encontrou um bom uso para o autoload, e vai deixar seus usuários mais felizes por não precisarem instalar o que não usarem :).

Referências:

http://www.rubyinside.com/ruby-techniques-revealed-autoload-1652.html
http://ruby-doc.org/core/classes/Module.html

Written by fernandoluizao

May 11, 2010 at 10:11 pm

Posted in Gems, Plugins, Ruby

Tagged with , , ,