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 by loading 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