Autorequire-0.0.0


#1

URLS

http://codeforpeople.com/lib/ruby/
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 noticed autorequire works for nested constants.  it 

does
# this by 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

enjoy.

-a