From: Trans Date: 2005-08-12T18:41:11+09:00 Subject: Re: Dear RubyGems: Perhaps a better way to override require... Ryan Leavengood wrote: > This does seem better, but only if everytime someone overrides require in > an included module they be sure to call super. > > Also it seems to be the alias method is fine, as long as everyone uses a > unique name for the old method: > > module Kernel > alias :_old_require_ :require > def require(s) > puts 'New require, now calling _old_require_...' > _old_require_(s) > end > end > > module Kernel > alias :_some_old_require_ :require > def require(s) > puts 'New require, now calling _some_old_require_...' > _some_old_require_(s) > end > end > > require 'English' > puts $PID > __END__ > > C:\_Ryan\ruby>ruby require_test.rb > New require, now calling _some_old_require_... > New require, now calling _old_require_... > 3408 > > If unique names aren't used, the result is an infinite loop. That's what I expected too. But when I tried, it didn't work so well. My aliased version was working fine until I installed RubyGems. Appaerently it was running my version twice. Thus escaping twice, "[]" -> "%5B%5D" -> "%255B%255D". Perhaps this is b/c RubyGems uses a rescue clause and retries and so ends up passing the name to my routine again. Not sure. But you also make a good point about my inheritance chain version. Someone else using the alias technique after mine would by pass mine altogether. It works with RubyGems only b/c RubyGems loads first. In thinking it over some, I suspect the best solution is either to change the built-in require to support an observer-type pattern, so one can tap into it. Or we simply need to agree on a standard, which I imagine would be basically: module Kernel # Always available bypass. # This should be built into ruby. alias __require__ require end module ARequireOverider def require( path ) # ... begin super( newpath ) # <----. rescue LoadError # or vise-versa super( path ) # <----' end end end class Object inculde ARequireOverider end T.