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