# Scoped\_require 0.0

**URL:** <https://www.ruby-forum.com/t/scoped-require-0-0/50432>\
**Category:** Ruby\
**Created:** [December 16, 2005, 8:09am UTC](https://www.ruby-forum.com/t/scoped-require-0-0/50432 "2005-12-16T08:09:35Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![twifkak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/a88e4f/32.png) [@twifkak](https://www.ruby-forum.com/u/twifkak)\
**Post date:** [December 16, 2005, 8:09am UTC](https://www.ruby-forum.com/t/scoped-require-0-0/50432/1 "2005-12-16T08:09:35Z")

</div>

… and from the substratum, it arises …

One-liner: scoped\_require provides an optional parameter to  
Kernel#require to allow you to shove the created modules/classes into  
some sandboxy container module. I use it to prevent namespace collision  
with an external library. It’s a hack. Heed the version number.

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

Browse or get at:

```
http://opensvn.csie.org/twifkak/trunk/scoped_require/scoped_require.rb

```

See the unit tests for usage. If you wanna run the unit tests, export  
the whole scoped\_require directory. And have the rubyful\_soup gem  
installed. Weirdo.

Several-liner:

So, I was writing a Rails app, and I was using RubyfulSoup to parse in  
some documents and feed some metadata into the database. Hoorah. (Thanks  
for the library, by the way!)

Then, I decided, “I should implement folksonomy!” As any standard human  
would do, I created a model object called Tag, and went on creating my  
tagging functionality.

I decide to run all of my tests again. Woo! Big honkin’ error in the  
feeder code. See, it seems that RubyfulSoup defines a class called Tag  
and shoves it in the top-level space – or, at least, tries to, before  
getting a “base class mismatch” error.

Well, I could contact the author and tell him to move his class out of  
my way, but I’m antisocial, and besides, I want it to work _now_! I  
could put my class in a module, but I WILL NOT SUCCUMB. No, no, I will  
put _his_ classes in a module. And I’ll do it without touching his code.  
(Look, ma, no CM issues!)

Well, being the naïve and lazy fellow I am, I try the simplest approach:  
module Soup  
require ‘rubyful\_soup’  
end

_whimper_ It doesn’t work. 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.

Judging by [http://www.rcrchive.net/rcr/show/289](http://www.rcrchive.net/rcr/show/289), I’m not the only person  
who had the desire for this capability. Is this “library” useful to  
other people? Would it be, if I got rid of the need for a require\_gem  
first? Or is this just some weird thing that only helps me? Do you have  
suggestions for making it suck less? Is it sad that my test code is  
prettier than my real code? Is there a library out there that already  
does this, but better? Will I become famous and wealthy thanks to this  
library (please oh please oh please)?

Thanks,  
Devin  
Yeah, I don’t mean to pick on RubyfulSoup so much… 's just on the  
brain…

---

<div class="post-metadata">

**Author:** ![twifkak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/a88e4f/32.png) [@twifkak](https://www.ruby-forum.com/u/twifkak)\
**Post date:** [December 16, 2005, 11:25am UTC](https://www.ruby-forum.com/t/scoped-require-0-0/50432/2 "2005-12-16T11:25:24Z")

</div>

On Fri, Dec 16, 2005 at 04:08:05PM +0900, Devin M. 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 😉

---

<div class="post-metadata">

**Author:** ![twifkak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/a88e4f/32.png) [@twifkak](https://www.ruby-forum.com/u/twifkak)\
**Post date:** [December 16, 2005, 2:59pm UTC](https://www.ruby-forum.com/t/scoped-require-0-0/50432/3 "2005-12-16T14:59:42Z")

</div>

Mauricio F. wrote:

> You also dislike alias\_method, don’t you? 😉

I tried to pollute the namespace as little as possible. (And then I  
refactored and created Module#find\_or\_create\_module, but whatever.) I  
also tried to be as ‘cute’ as possible (but that was a tertiary  
concern).

> wouldn’t that break code like
> 
> # foo.rb
> 
> class String
> 
> # instead of class ::String
> 
> def foo; “foo #{self}” end  
> end

Good point, yes… I suppose I could inject #clones of the toplevel  
namespace’s constants into the container module… 'twould be a little  
performance-heavy, so maybe I’d make that an option, à la:  
require ‘foo’, :module =\> :Foo, :import =\> [String, Hash]  
Would that work? Do you have a better idea?

> # 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 $"?

I should be deadling with that, now. Without running the above code, I’m  
pretty sure 'something’ll get loaded under A::B. And my require override  
uses @\_\_require\_feature rather than $", so it’s specific to each  
container module.

Although, admittedly, I probably could use a couple of unit tests to  
test the interaction between scoped requires and non-scoped requires  
(and $").

> 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 😉

Well, definitely more than one file – it was in my requirements (using  
RubyfulSoup) that nested requires work.\* But yeah, I couldn’t imagine  
that require ‘rails’, :module =\> :Rails would work. 😛

Thanks for the feedback. I may add the import thing later.

Devin

- Well, sort of. It’s actually the main file, rubyful\_soup.rb, that  
defines the Tag class, not its dependency, sgml\_parser.rb, so I could’ve  
gotten away with not handling nested requires. But I was having fun…  
🙂

---

<div class="post-metadata">

**Author:** ![twifkak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/a88e4f/32.png) [@twifkak](https://www.ruby-forum.com/u/twifkak)\
**Post date:** [December 16, 2005, 9:57pm UTC](https://www.ruby-forum.com/t/scoped-require-0-0/50432/4 "2005-12-16T21:57:02Z")

</div>

Devin M. wrote:

> Mauricio F. wrote:
> 
> > You also dislike alias\_method, don’t you? 😉
> 
> I tried to pollute the namespace as little as possible. (And then I  
> refactored and created Module#find\_or\_create\_module, but whatever.) I  
> also tried to be as ‘cute’ as possible (but that was a tertiary  
> concern).
> 
> > wouldn’t that break code like
> > 
> > # foo.rb
> > 
> > class String
> > 
> > # instead of class ::String
> > 
> > def foo; “foo #{self}” end  
> > end
> 
> Good point, yes… I suppose I could inject #clones of the toplevel  
> namespace’s constants into the container module… 'twould be a little  
> performance-heavy, so maybe I’d make that an option, à ¬a:  
> require ‘foo’, :module =\> :Foo, :import =\> [String, Hash]  
> Would that work? Do you have a better idea?

I recall talking about this some time ago, either here  
or on #ruby-lang, and someone (Austin Z., maybe?)  
came up with a workable solution. I will see if I can  
locate that code. In the meanwhile, see if you can  
search the archives for it.

> > # 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 $"?
> 
> I should be deadling with that, now. Without running the above code, I’m  
> pretty sure 'something’ll get loaded under A::B. And my require override  
> uses @\_\_require\_feature rather than $", so it’s specific to each  
> container module.
> 
> Although, admittedly, I probably could use a couple of unit tests to  
> test the interaction between scoped requires and non-scoped requires  
> (and $").
> 
> > 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 😉
> 
> Well, definitely more than one file – it was in my requirements (using  
> RubyfulSoup) that nested requires work.\* But yeah, I couldn’t imagine  
> that require ‘rails’, :module =\> :Rails would work. 😛
> 
> Thanks for the feedback. I may add the import thing later.
> 
> Devin
> 
> - Well, sort of. It’s actually the main file, rubyful\_soup.rb, that  
> defines the Tag class, not its dependency, sgml\_parser.rb, so I could’ve  
> gotten away with not handling nested requires. But I was having fun…  
> 🙂

E
