URLS

http://codeforpeople.com/lib/ruby/autorequire/
http://rubyforge.org/frs/?group_id=1024

ABOUT

autorequire is sleeker, more aerodynamic, greasier version of autoload.

like autoload it's primary usage is to speed up the load time of large
libraries which, themselves, do many requires.

INSTALL

gem install autorequire

VERSION

0.0.0

HISTORY

0.0.0 :

  initial release

AUTHOR

ara [dot] t [dot] howard [at] noaa [dot] gov

SAMPLES

<========< emsg.rb >========>

~ > cat emsg.rb 
  #
  # rescues err and prints msg - support method for samples/*
  #
  def emsg
    yield
  rescue Exception => e
    puts "#{ e } (#{ e.class })!"
  end

<========< libgen.rb >========>

~ > cat libgen.rb 
  #
  # generates a temporaray ruby lib - support method for samples/*
  #
  require 'fileutils'
  def libgen path, libdir = './.lib/'
    f, fu = File, FileUtils
    dirname, basename = f.split path
    dirname = f.join libdir, dirname
    fu.mkdir_p dirname
    path = f.join dirname, basename
    open(path,'w'){|fd| fd << yield}
    at_exit{ Dir.glob(f.join(libdir, '*')){|e| fu.rm_rf e} }
    path
  end

<========< sample/a.rb >========>

~ > cat sample/a.rb

  #
  # simple use is much like autoload
  #
  emsg{ p Queue }

  autorequire 'Queue', 'thread'

  emsg{ p Queue }

~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/a.rb

  Queue (NameError)!
  Queue

<========< sample/b.rb >========>

~ > cat sample/b.rb

  #
  # but we can also specify nested classes.  note the alternative hash syntax.
  # a list of const => lib pairs may also be given.
  #
  emsg{ p CGI::Session }

  autorequire 'CGI::Session' => 'cgi/session'

  emsg{ p CGI::Session }

~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/b.rb

  CGI (NameError)!
  CGI::Session

<========< sample/c.rb >========>

~ > cat sample/c.rb

  #
  # like autoload, calling autorequire on a class defines the lib to be loaded
  # when the const_missing hook for __that__ class is called
  #
  class C
    lib = libgen('a.rb'){ 'class C::A; end' }

    emsg{ p A }

    autorequire 'A' => lib 

    emsg{ p A }
  end

  emsg{ p A}
  emsg{ p C::A}

~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/c.rb

  A (NameError)!
  C::A
  A (NameError)!
  C::A

<========< sample/d.rb >========>

~ > cat sample/d.rb

  #
  # however, we can scope the constant to the top-level, even from within
  # another class
  #
  emsg{ p A }

  class C
    lib = libgen('a.rb'){ 'class ::A; end' }
    autorequire '::A' => lib 
    emsg{ p A }
    emsg{ p ::A }
  end

  emsg{ p A }

~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/d.rb

  A (NameError)!
  A (NameError)!
  A
  A

<========< sample/e.rb >========>

~ > cat sample/e.rb

  #
  # this is a nice way to setup bulk autoloads in a large library 
  #
  emsg{ p Net::Ftp }
  emsg{ p CGI::Session }

  module M
    autorequire '::Net::FTP' => 'net/ftp', '::CGI::Session' => 'cgi/session'
  end

  emsg{ p Net::FTP }
  emsg{ p CGI::Session }

~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/e.rb

  Net (NameError)!
  CGI (NameError)!
  Net::FTP
  CGI::Session

<========< sample/f.rb >========>

~ > cat sample/f.rb

  #
  # you may have notice autorequire works for nested constants.  it does this be
  # dynamically setting up proxy modules to resolve a name.  once the names have
  # actually been resolved the proxy is dropped.
  #
  emsg{ p Net }
  emsg{ p CGI }

  autorequire '::Net::FTP' => 'net/ftp', '::CGI::Session' => 'cgi/session'

  emsg{ p Net }
  emsg{ p CGI }

  emsg{ p Net::FTP }
  emsg{ p CGI::Session }

  emsg{ p Net }
  emsg{ p CGI }

~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/f.rb

  Net (NameError)!
  CGI (NameError)!
  "ConstProxy(Net)"
  "ConstProxy(CGI)"
  Net::FTP
  CGI::Session
  Net
  CGI

<========< sample/g.rb >========>

~ > cat sample/g.rb

  #
  # this actually works for arbitrarily deep const nestings
  #
  lib =
    libgen('a/b/c/d.rb'){
      '
      module A
        module B
          module C
            class D
            end
          end
        end
      end
      '
    }

  autorequire 'A::B::C::D' => lib

  p A
  p A::B
  p A::B::C
  p A::B::C::D
  p A::B::C
  p A::B
  p A

~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/g.rb

  "ConstProxy(A)"
  "ConstProxy(B)"
  "ConstProxy(C)"
  A::B::C::D
  A::B::C
  A::B
  A

<========< sample/h.rb >========>

~ > cat sample/h.rb

  #
  # if you don't specify which lib to load it's name is guessed using a rather
  # naive approach.  
  #
  emsg{ p PStore }
  emsg{ p CGI::Session }
  emsg{ p FileUtils }

  autorequire 'PStore'       # requires 'pstore'
  autorequire 'CGI::Session' # requires 'cgi/session'
  autorequire '::FileUtils'  # requires 'fileutils'

  emsg{ p PStore }
  emsg{ p CGI::Session }
  emsg{ p FileUtils }

~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/h.rb

  PStore (NameError)!
  CGI (NameError)!
  FileUtils
  PStore
  CGI::Session
  FileUtils

<========< sample/i.rb >========>

~ > cat sample/i.rb

  #
  # if you're feeling risque you can set Autorequire.everything = true to use
  # this default loading for __any__ const missing.
  #
  Autorequire.everything = 42 

  emsg{ p PStore }
  emsg{ p CGI::Session }
  emsg{ p FileUtils }

~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/i.rb

  PStore
  CGI::Session
  FileUtils

<========< sample/j.rb >========>

~ > cat sample/j.rb

  #
  # you do, at least, get a meaningful error if the const to lib translation
  # fails
  #
  autorequire 'FuBar' => 'does-not-exist.rb'

  emsg{ p FuBar }

~ > ruby -r ./emsg.rb -r ./libgen.rb -r ./lib/autorequire.rb sample/j.rb

  resolving <FuBar> by loading <does-not-exist.rb> failed (Autorequire::NameError)!

CAVEATS

this library is experimental.  nonetheless it's relatively straight forward
and i have no plans to change it's interface - though i may add to it in
future release.

LICENSE

same as ruby's