On Fri, Dec 16, 2005 at 04:08:05PM +0900, Devin Mullins wrote:
> Example usage:
>    require 'rubygems'
>    require_gem 'rubyful_soup' # luckily this doesn't have autorequire set
>    require 'rubyful_soup', :module => :Soup # here's the magic
>    assert_equal 'constant', defined? Soup::BeautifulSoup
[...]
> I eventually settle on this can of ugly:
>    module Soup
>       eval IO.read('sgml_parser.rb')
>       $" << 'sgml_parser.rb'
>       eval IO.read('rubyful_soup.rb')
>    end
> 
> Yeah. Cry. So I packaged up that can of ugly into a pretty little 
> #require override, so that I never have to think about it again.

You also dislike alias_method, don't you? ;-)
    class Object
      old_require = method :require
      define_method :require do |*args|
...

As for the actual low-level mechanism:
      eval <<-SCOPED
        module #{mod.name}
          #{IO.read("#{file_path}")}
        end
      SCOPED

wouldn't that break code like

# foo.rb
class String
# instead of class ::String
  def foo; "foo #{self}" end
end

Foo = Struct.new(:bar){ def doit; bar.foo end }
#=================================================================
# in myapp.rb
# require 'foo', :module => :Foo
# Foo::Foo.bar

Foo.new("foobar").bar                              # => "foobar"


There's another tricky issue regarding the transitivity of scoped_require:

# a.rb
require 'b', :module => :B
...
#=================================================================
# b.rb
require 'something'
...
#=================================================================
# app.rb
require 'a', :module => :A

Should 'something' be scoped to B, A, A::B, or not at all?
And if it is loaded under some module, should it be added to $"?


So it seems scoped_require would work best with 1-file libs that don't
mess with code classes. In other cases, it could still be useful: there's
nothing wrong with encouraging lecture ;-)

-- 
Mauricio Fernandez