From: TRANS Date: 2005-09-27T05:55:24+09:00 Subject: Require Namepaces and RubyGems' effect on LoadPath problem I've added namespaces to require. Works like this: $LOAD_SPACE[ 'myspace' ] = [ 'a/path', 'another/path' ] require 'myspace:script.rb' The load spaces are File.join'd with the entries in $LOAD_PATH, $LOAD_PATH is unshifted with those entries and the built-in #require is called. When complete it removes those namespace paths. The key thing to keep in mind here: this allows for *relative* paths within the context of the namespace require. For example: $LOAD_SPACE[ 'tim' ] = [ 'tim/path' ] require 'tim:file.rb' tim/path/file.rb: require 'file2.rb' file2.rb is located at tim/path/file2.rb. The above require works fine w/o using 'tim/path/file2.rb' b/c the path defined by the namespace has been temporarily placed in $LOAD_PATH in the first require call. So this works great in itself. BUT Gems will add any matches it finds *permanently* to the $LOAD_PATH. Hence if I distribute this via Gems I'm pretty sure this will get all messed up, and won't properly remove what this only *temporarily* adds. Suggestions? Below is the code. T. # This module allows kernel methods to be overridden # in a OOP fashion. SubKernel is appended to Object, # allowing it to slip in prior to the original Kernel. # # In also adds a new #require sub-method that allows for # namespaces. # module SubKernel $LOAD_SPACE = {} # A new #require sub-method that allows for namespaces. def require( fpath ) success = false name, space = fpath.split(':').reverse if space and $LOAD_SPACE.key?( space ) load_path = $LOAD_PATH.dup begin search_path = [] $LOAD_PATH.each { |lp| $LOAD_SPACE[ space ].each { |ls| if File.directory?( File.join( lp, ls ) ) search_path << File.join( lp, ls ) end } } $LOAD_PATH.replace(search_path | $LOAD_PATH) success = super( name ) ensure $LOAD_PATH.replace($LOAD_PATH - search_path) #$LOAD_PATH.replace(load_path) # Thwart Gems? end else success = super( fpath ) end success end end class Object include SubKernel end