# Dynamically modifying modules to avoid namespace collisions

**URL:** <https://rubytalk.org/t/dynamically-modifying-modules-to-avoid-namespace-collisions/27489>\
**Category:** ruby-talk\
**Created:** [17 May 2006 00:19 UTC](https://rubytalk.org/t/dynamically-modifying-modules-to-avoid-namespace-collisions/27489 "2006-05-17T00:19:16Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Wes\_Gamble](https://avatars.discourse-cdn.com/v4/letter/w/258eb7/32.png) [@Wes\_Gamble](https://rubytalk.org/u/Wes_Gamble)\
**Post date:** [17 May 2006 00:19 UTC](https://rubytalk.org/t/dynamically-modifying-modules-to-avoid-namespace-collisions/27489/1 "2006-05-17T00:19:16Z")

</div>

All,

I have a namespace collision problem between a Rubygem (htmltools 1.09)  
and a Rails framework class (in ActionPack 1.12.1).

In order to use both, I will need to modify the namespace of one of  
them.

However, I would really like to not have to modify the existing gems and  
I was thinking that maybe there might be some clever way to use the  
Module class to "wrap" the offending module redefine it's namespace.

Has anyone ever done anything like this?

Otherwise, I will be looking at "taking ownership" of the gem code and  
moving it to a locally - controlled location essentially freezing the  
version of that Gem for my application

Thanks,  
Wes

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Wes\_Gamble](https://avatars.discourse-cdn.com/v4/letter/w/258eb7/32.png) [@Wes\_Gamble](https://rubytalk.org/u/Wes_Gamble)\
**Post date:** [17 May 2006 00:21 UTC](https://rubytalk.org/t/dynamically-modifying-modules-to-avoid-namespace-collisions/27489/2 "2006-05-17T00:21:29Z")

</div>

Hey, I just thought of something.

Is there a way to unload ("un-require") a module at runtime? Is there a  
way to load ("re-require") a module at runtime?

Thanks,  
Wes

Wes Gamble wrote:

> **···**
>
> > All,
> > 
> > I have a namespace collision problem between a Rubygem (htmltools 1.09)  
> > and a Rails framework class (in ActionPack 1.12.1).
> > 
> > In order to use both, I will need to modify the namespace of one of  
> > them.
> > 
> > However, I would really like to not have to modify the existing gems and  
> > I was thinking that maybe there might be some clever way to use the  
> > Module class to "wrap" the offending module redefine it's namespace.
> > 
> > Has anyone ever done anything like this?
> > 
> > Otherwise, I will be looking at "taking ownership" of the gem code and  
> > moving it to a locally - controlled location essentially freezing the  
> > version of that Gem for my application
> > 
> > Thanks,  
> > Wes
> 
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Logan\_Capaldo](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@Logan\_Capaldo](https://rubytalk.org/u/Logan_Capaldo)\
**Post date:** [17 May 2006 00:34 UTC](https://rubytalk.org/t/dynamically-modifying-modules-to-avoid-namespace-collisions/27489/3 "2006-05-17T00:34:34Z")

</div>

> Hey, I just thought of something.
> 
> Is there a way to unload ("un-require") a module at runtime? Is there a  
> way to load ("re-require") a module at runtime?
> 
> Thanks,  
> Wes

I think you may be over-estimating the relationship between modules and files.  
One does not require modules, one requires files. One file may have many modules in it, or none. Regardless one can still 'require' that file.

One way to hack something so it gets stuck in a module is:

module Protect  
&nbsp;&nbsp;&nbsp;eval(File.read("path/to/file.rb"))  
end

Then you access all the classes defined in file.rb like:

Protect::Node.new # etc.

> **···**
>
> On May 16, 2006, at 8:21 PM, Wes Gamble wrote:
> 
> > Wes Gamble wrote:
> > 
> > > All,
> > > 
> > > I have a namespace collision problem between a Rubygem (htmltools 1.09)  
> > > and a Rails framework class (in ActionPack 1.12.1).
> > > 
> > > In order to use both, I will need to modify the namespace of one of  
> > > them.
> > > 
> > > However, I would really like to not have to modify the existing gems and  
> > > I was thinking that maybe there might be some clever way to use the  
> > > Module class to "wrap" the offending module redefine it's namespace.
> > > 
> > > Has anyone ever done anything like this?
> > > 
> > > Otherwise, I will be looking at "taking ownership" of the gem code and  
> > > moving it to a locally - controlled location essentially freezing the  
> > > version of that Gem for my application
> > > 
> > > Thanks,  
> > > Wes
> > 
> > --  
> > Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Gregory\_Seidman](https://avatars.discourse-cdn.com/v4/letter/g/eb9ed0/32.png) [@Gregory\_Seidman](https://rubytalk.org/u/Gregory_Seidman)\
**Post date:** [17 May 2006 14:11 UTC](https://rubytalk.org/t/dynamically-modifying-modules-to-avoid-namespace-collisions/27489/4 "2006-05-17T14:11:10Z")

</div>

[...]  
} One does not require modules, one requires files. One file may have  
} many modules in it, or none. Regardless one can still 'require' that  
} file.  
}  
} One way to hack something so it gets stuck in a module is:  
}  
} module Protect  
} eval(File.read("path/to/file.rb"))  
} end  
}  
} Then you access all the classes defined in file.rb like:  
}  
} Protect::Node.new # etc.

This is a great idiom, but it needs to be able to function as a (nearly)  
drop-in replacement for require. This means that I need to be able to find  
the file in the search path that require would normally use. Consider the  
following:

def find\_require\_file(filename)  
&nbsp;&nbsp;# NEED IMPLEMENTATION HERE  
end

def namespace\_get(str)  
&nbsp;&nbsp;str.to\_s.split("::").inject(Object) { |ns,name| ns.const\_get(name) }  
end

def require\_within(module\_name, filename)  
&nbsp;&nbsp;file = find\_require\_file(file)  
&nbsp;&nbsp;mod = module\_name  
&nbsp;&nbsp;case module\_name  
&nbsp;&nbsp;&nbsp;&nbsp;when Module,Class  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#noop  
&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mod = namespace\_get(mod)  
&nbsp;&nbsp;end  
&nbsp;&nbsp;mod.instance\_eval { eval File.read(file) }  
end

This is untested, and I don't know how to implement that find\_require\_file,  
but the idea is that the following should work:

module Foo  
&nbsp;&nbsp;module Bar  
&nbsp;&nbsp;end  
end

require\_within Foo::Bar, "date"

x = Foo::Bar::Date.today

Anyone want to implement find\_require\_file and test the idea?

--Greg

> **···**
>
> On Wed, May 17, 2006 at 09:34:34AM +0900, Logan Capaldo wrote:

---

<div class="post-metadata">

**Author:** ![Wes\_Gamble](https://avatars.discourse-cdn.com/v4/letter/w/258eb7/32.png) [@Wes\_Gamble](https://rubytalk.org/u/Wes_Gamble)\
**Post date:** [17 May 2006 15:23 UTC](https://rubytalk.org/t/dynamically-modifying-modules-to-avoid-namespace-collisions/27489/5 "2006-05-17T15:23:42Z")

</div>

Greg,

This is a good idea. Would make it easier to handle these sorts of  
issues.  
I may give it a shot. I'll let you know if I come up with anything.

Wes

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Wes\_Gamble](https://avatars.discourse-cdn.com/v4/letter/w/258eb7/32.png) [@Wes\_Gamble](https://rubytalk.org/u/Wes_Gamble)\
**Post date:** [17 May 2006 17:20 UTC](https://rubytalk.org/t/dynamically-modifying-modules-to-avoid-namespace-collisions/27489/6 "2006-05-17T17:20:17Z")

</div>

Greg,

How does this

str.to\_s.split("::").inject(Object) { |ns,name| ns.const\_get(name) }

work?

Wes

Gregory Seidman wrote:

> **···**
>
> > On Wed, May 17, 2006 at 09:34:34AM +0900, Logan Capaldo wrote:  
> > [...]  
> > } One does not require modules, one requires files. One file may have  
> > } many modules in it, or none. Regardless one can still 'require' that  
> > } file.  
> > }  
> > } One way to hack something so it gets stuck in a module is:  
> > }  
> > } module Protect  
> > } eval(File.read("path/to/file.rb"))  
> > } end  
> > }  
> > } Then you access all the classes defined in file.rb like:  
> > }  
> > } Protect::Node.new # etc.
> > 
> > This is a great idiom, but it needs to be able to function as a (nearly)  
> > drop-in replacement for require. This means that I need to be able to  
> > find  
> > the file in the search path that require would normally use. Consider  
> > the  
> > following:
> > 
> > def find\_require\_file(filename)  
> > &nbsp;&nbsp;# NEED IMPLEMENTATION HERE  
> > end
> > 
> > def namespace\_get(str)  
> > &nbsp;&nbsp;str.to\_s.split("::").inject(Object) { |ns,name| ns.const\_get(name) }  
> > end
> > 
> > def require\_within(module\_name, filename)  
> > &nbsp;&nbsp;file = find\_require\_file(file)  
> > &nbsp;&nbsp;mod = module\_name  
> > &nbsp;&nbsp;case module\_name  
> > &nbsp;&nbsp;&nbsp;&nbsp;when Module,Class  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#noop  
> > &nbsp;&nbsp;&nbsp;&nbsp;else  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mod = namespace\_get(mod)  
> > &nbsp;&nbsp;end  
> > &nbsp;&nbsp;mod.instance\_eval { eval File.read(file) }  
> > end
> > 
> > This is untested, and I don't know how to implement that  
> > find\_require\_file,  
> > but the idea is that the following should work:
> > 
> > module Foo  
> > &nbsp;&nbsp;module Bar  
> > &nbsp;&nbsp;end  
> > end
> > 
> > require\_within Foo::Bar, "date"
> > 
> > x = Foo::Bar::Date.today
> > 
> > Anyone want to implement find\_require\_file and test the idea?
> > 
> > --Greg
> 
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Logan\_Capaldo](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@Logan\_Capaldo](https://rubytalk.org/u/Logan_Capaldo)\
**Post date:** [17 May 2006 20:03 UTC](https://rubytalk.org/t/dynamically-modifying-modules-to-avoid-namespace-collisions/27489/7 "2006-05-17T20:03:24Z")

</div>

def find\_require\_file(filename)  
&nbsp;&nbsp;&nbsp;$LOAD\_PATH.each do |directory|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[".rb", ".so", ".dll"].each do |ext|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if File.exists?(f = File.join(directory, filename + ext))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return f  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;# otherwise we didn't find it  
&nbsp;&nbsp;&nbsp;raise 'Could not find #{filename} in $LOAD\_PATH.'  
end

> **···**
>
> On May 17, 2006, at 10:11 AM, Gregory Seidman wrote:
> 
> > def find\_require\_file(filename)  
> > &nbsp;&nbsp;# NEED IMPLEMENTATION HERE  
> > end

---

<div class="post-metadata">

**Author:** ![Daniel\_Schierbeck](https://avatars.discourse-cdn.com/v4/letter/d/dfb087/32.png) [@Daniel\_Schierbeck](https://rubytalk.org/u/Daniel_Schierbeck)\
**Post date:** [17 May 2006 18:06 UTC](https://rubytalk.org/t/dynamically-modifying-modules-to-avoid-namespace-collisions/27489/8 "2006-05-17T18:06:03Z")

</div>

Wes Gamble wrote:

> How does this
> 
> &nbsp;&nbsp;str.to\_s.split("::").inject(Object) { |ns,name| ns.const\_get(name) }
> 
> work?

It takes a string on the form "A:🅱:C" and splits it into an array; ["A", "B", "C"]. When calling #inject on that array, you iterate over each element, yielding them to the block (the second parameter). The first parameter is the result of the last call to the block, or, if it's the first element, the default value, here Object.

&nbsp;&nbsp;&nbsp;%w(A B C).inject(Object) {|parent, child| parent.const\_get(child) }

is the same as

&nbsp;&nbsp;&nbsp;Object.const\_get(:A).const\_get(:B).const\_get(:C)

Hope that made it clearer

Daniel

---

<div class="post-metadata">

**Author:** ![Logan\_Capaldo](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@Logan\_Capaldo](https://rubytalk.org/u/Logan_Capaldo)\
**Post date:** [17 May 2006 20:14 UTC](https://rubytalk.org/t/dynamically-modifying-modules-to-avoid-namespace-collisions/27489/9 "2006-05-17T20:14:51Z")

</div>

Actually in retrospect, I should have used double quotes in the raise and if you know you're always gonna be eval-ing these files, you probably want to get rid of the .dll and .so extensions.

> **···**
>
> On May 17, 2006, at 4:03 PM, Logan Capaldo wrote:
> 
> > On May 17, 2006, at 10:11 AM, Gregory Seidman wrote:
> > 
> > > def find\_require\_file(filename)  
> > > &nbsp;&nbsp;# NEED IMPLEMENTATION HERE  
> > > end
> > 
> > def find\_require\_file(filename)  
> > &nbsp;&nbsp;$LOAD\_PATH.each do |directory|  
> > &nbsp;&nbsp;&nbsp;&nbsp;[".rb", ".so", ".dll"].each do |ext|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if File.exists?(f = File.join(directory, filename + ext))  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return f  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;end  
> > &nbsp;&nbsp;# otherwise we didn't find it  
> > &nbsp;&nbsp;raise 'Could not find #{filename} in $LOAD\_PATH.'  
> > end

---

<div class="post-metadata">

**Author:** ![Gregory\_Seidman](https://avatars.discourse-cdn.com/v4/letter/g/eb9ed0/32.png) [@Gregory\_Seidman](https://rubytalk.org/u/Gregory_Seidman)\
**Post date:** [17 May 2006 20:48 UTC](https://rubytalk.org/t/dynamically-modifying-modules-to-avoid-namespace-collisions/27489/10 "2006-05-17T20:48:06Z")

</div>

} Greg,  
}  
} How does this  
}  
} str.to\_s.split("::").inject(Object) { |ns,name| ns.const\_get(name) }  
}  
} work?

Magic 🙂

So suppose you have a string "Foo::Bar" and you want to retrieve the module  
(or class, or other constant) Bar from the module (or class) Foo. (For  
simplicity we will assume that both are modules.) First, we make sure it's  
a string and split it on "::" which results in the array ["Foo", "Bar"].  
Now we use inject with its optional starting object.

For the first iteration of inject, ns = Object and name = "Foo" so the  
value of ns.const\_get(name) is Foo (the module). On the next iteration,  
ns = Foo and name = "Bar" so the value of ns.const\_get(name) is Bar (the  
module). That's the end of the iteration, so the value of the entire line  
is Bar, which is the value of the method call, which is what you wanted in  
the first place.

} Wes  
--Greg

> **···**
>
> On Thu, May 18, 2006 at 02:20:17AM +0900, Wes Gamble wrote:

---

<div class="post-metadata">

**Author:** ![Logan\_Capaldo](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@Logan\_Capaldo](https://rubytalk.org/u/Logan_Capaldo)\
**Post date:** [18 May 2006 01:01 UTC](https://rubytalk.org/t/dynamically-modifying-modules-to-avoid-namespace-collisions/27489/11 "2006-05-18T01:01:45Z")

</div>

One more thing, this won't work with gems unless you use require\_gem.

e.g.

% irb  
irb(main):001:0\>  
irb(main):002:0\* def find\_require\_file(filename)  
irb(main):003:1\> $LOAD\_PATH.each do |directory|  
irb(main):004:2\* [".rb", ".so", ".dll"].each do |ext|  
irb(main):005:3\* if File.exists?(f = File.join(directory, filename + ext))irb(main):006:4\> return f  
irb(main):007:4\> end  
irb(main):008:3\> end  
irb(main):009:2\> end  
irb(main):010:1\> # otherwise we didn't find it  
irb(main):011:1\* raise 'Could not find #{filename} in $LOAD\_PATH.'  
irb(main):012:1\> end  
=\> nil  
irb(main):013:0\> find\_require\_file('parse\_tree')  
RuntimeError: Could not find #{filename} in $LOAD\_PATH.  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):11:in `find\_require\_file'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):13  
irb(main):014:0\> require 'rubygems'  
=\> true  
irb(main):015:0\> find\_require\_file('parse\_tree')  
RuntimeError: Could not find #{filename} in $LOAD\_PATH.  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):11:in `find\_require\_file'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):15  
irb(main):016:0\> require\_gem 'ParseTree'  
=\> true  
irb(main):017:0\> find\_require\_file('parse\_tree')  
=\> "/usr/local/ruby/lib/ruby/gems/1.8/gems/ParseTree-1.4.1/lib/parse\_tree.rb"  
irb(main):018:0\>

Since of how rubygems alter the load path. If you are using a gem, as long as it doesn't use the deprecated (and evil) autorequire attribute, you should still be able to safely stick it in its own namespace.

> **···**
>
> On May 17, 2006, at 4:14 PM, Logan Capaldo wrote:
> 
> > On May 17, 2006, at 4:03 PM, Logan Capaldo wrote:
> > 
> > > On May 17, 2006, at 10:11 AM, Gregory Seidman wrote:
> > > 
> > > > def find\_require\_file(filename)  
> > > > &nbsp;&nbsp;# NEED IMPLEMENTATION HERE  
> > > > end
> > > 
> > > def find\_require\_file(filename)  
> > > &nbsp;&nbsp;$LOAD\_PATH.each do |directory|  
> > > &nbsp;&nbsp;&nbsp;&nbsp;[".rb", ".so", ".dll"].each do |ext|  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if File.exists?(f = File.join(directory, filename + ext))  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return f  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > > &nbsp;&nbsp;end  
> > > &nbsp;&nbsp;# otherwise we didn't find it  
> > > &nbsp;&nbsp;raise 'Could not find #{filename} in $LOAD\_PATH.'  
> > > end
> > 
> > Actually in retrospect, I should have used double quotes in the raise and if you know you're always gonna be eval-ing these files, you probably want to get rid of the .dll and .so extensions.
