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.