<?xml version='1.0' encoding='UTF-8'?>
<elementos_gw>
  <documento>
    <id>957</id>
    <autor>5</autor>
    <nome>Autoload do Ruby como no PHP</nome>
    <nome_facil>autoload do ruby como no php</nome_facil>
    <criacao>2011-02-24 20:52:35</criacao>
    <alteracao>2012-07-01 18:13:24</alteracao>
    <texto>Quem trabalhou com OOP em PHP e começa a aprender Ruby vai logo sentir falta do [http://www.php.net/manual/pt_BR/language.oop5.autoload.php __autoload do PHP].

O Ruby já tem [http://ruby-doc.org/core/Module.html#method-i-autoload 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, &quot;minhaclasse.rb&quot;
}}}

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 &quot;minhaclasse.rb&quot;
}}}

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 &quot;MinhaClasse&quot;, a função {{{__autoload}}} irá converter isso para um nome de arquivo (por exemplo, &quot;minhaclasse.inc&quot;; 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 [http://www.germanforblack.com/articles/ruby-autoload 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 &lt;&lt; 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 =&gt; 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
}}}

</texto>
    <publico>1</publico>
    <original>0</original>
    <anterior>0</anterior>
    <versao>0</versao>
    <traducao>0</traducao>
    <propriedade>
      <nome>linguagem</nome>
      <valor>ruby.</valor>
      <publico>1</publico>
    </propriedade>
    <propriedade>
      <nome>categ</nome>
      <valor>list</valor>
      <publico>1</publico>
    </propriedade>
    <propriedade>
      <nome>categ</nome>
      <valor>artigos</valor>
      <publico>1</publico>
    </propriedade>
    <propriedade>
      <nome>área</nome>
      <valor>programação</valor>
      <publico>1</publico>
    </propriedade>
  </documento>
</elementos_gw>
