Autoload do Ruby como no PHP
2012-07-01 18:13:24
2011-02-24 20:52:35
Autor: Sony Santos
https://gigawiki.com/sony/autoload-do-ruby-como-no-php
Permalink: https://gigawiki.com/957
área = programação; categ = artigos, list; linguagem = ruby.
Quem trabalhou com OOP em PHP e começa a aprender Ruby vai logo sentir falta do __autoload do PHP.

O Ruby já tem autoload, mas na prática parece inútil, para quem vem do PHP.

No Ruby, o objetivo do autoload é apenas não ocupar memória sem necessidade, deixando para carregar os arquivos somente quando a classe ou módulo forem requeridos. Muito bem, mas para isso você precisa digitar mais do que digitaria com require: além de especificar o nome do arquivo, tem que digitar as constantes (classes, etc.) que estão no arquivo. Por exemplo:

autoload :MinhaClasse, "minhaclasse.rb"

Eu penso que os computadores foram feitos para ajudar o homem, e isso inclui o programador. Do ponto de vista do programador (e não da máquina), seria muito mais fácil usar:

require "minhaclasse.rb"

A não ser que os recursos sejam críticos, o tempo de desenvolvimento e manutenção é mais importante neste caso.

No PHP, você define apenas uma vez uma função que irá adivinhar o nome do arquivo a partir do nome da classe, e aí nunca mais precisa se preocupar! Você não tem que especificar nada!!! Quando for feita uma referência a "MinhaClasse", a função __autoload irá converter isso para um nome de arquivo (por exemplo, "minhaclasse.inc"; você pode programar __autoload como quiser) e tentará incluir esse arquivo. É muito mais prático!

Felizmente o Ruby é uma linguagem muito maleável e, baseado em uma dica, desenvolvi a minha versão:

# autoload como em PHP
# http://gigawiki.com/sony/autoload-do-ruby-como-no-php

# altera Object#const_missing
#
class Object

  # trata-se de um método da classe, e não do objeto
  class << self

    # mantém o método original em old_const_missing, e o torna privado
    alias_method :old_const_missing, :const_missing
    private :old_const_missing

    # redefine método chamado quando a constante não é encontrada
    def const_missing(const)

      # adivinha um nome de arquivo (use seu algoritmo preferido)
      filename = const.to_s.downcase

      begin
        # tenta requeri-lo
        require filename

        # se conseguiu, retorna a constante que faltava
        const_get(const)

      rescue LoadError => e
        if e.message.include? filename

          # se não conseguiu porque essa constante não existe, usa o algoritmo antigo.
          old_const_missing(const)

        else

          # se não conseguiu por outro motivo, manifeste-se.
          raise

        end
      end
    end
  end
end

blog comments powered by Disqus