From: Jacob Fugal Date: 2006-06-09T02:19:23+09:00 Subject: Re: Requiring a file into a different namespace On 6/7/06, transfire@gmail.com wrote: > Use #load. Not tested but it will be something like: > > ["a","b"].each do |name| > sandbox = Module.new { load "#{name}.rb" } > > survey = sandbox::Survey.new > > puts survey.name > end Unfortunately, this won't work. You can't even do this directly: $ cat a.rb sandbox = Module.new{ module Survey; end } p sandbox::Survey rescue puts "sandbox has no Survey" p Survey rescue puts "there is no top level Survey" $ ruby a.rb sandbox has no Survey Survey So, you can see, the Survey module is defined at the top level, rather than inside the anonymous sandbox. The same thing happens for module_eval, instance_eval and class_eval in block form. However, in string form, module_eval does the trick: $ cat b.rb sandbox = Module.new sandbox.module_eval "module Survey; end" p sandbox::Survey rescue puts "sandbox has no Survey" p Survey rescue puts "there is no top level Survey" $ ruby b.rb #::Survey there is no top level Survey This is simply enough extended for getting the string to be eval'd via File.read: $ cat source.rb module Survey; end $ cat target.rb sandbox = Module.new sandbox.module_eval File.read("source.rb") p sandbox::Survey rescue puts "sandbox has no Survey" p Survey rescue puts "there is no top level Survey" $ ruby target.rb #::Survey there is no top level Survey What I really want to know is this: Kernel#load allows a parameter that wraps the loaded file in an anonymous module, so as not to pollute the global namespace. But that anonymous module is discarded -- as far as I can tell, the only use for this style of load is if the only portion of the file you're interested in is the side effects. I suggest one of two changes. 1) Change Kernel#load to return the anonymous module when the wrap parameter is true. Currently, the return value of Kernel#load is always true (failure results in an exception), so there should be no code relying on the current return value. 2) Since the wrap parameter can only be true or false right now, change that parameter to accept a module. The behavior when that parameter is false/nil/true is unchanged for backwards compatibility, but if the parameter is a module, load the file into that module instead of into a new anonymous module. How do these ideas sound to people? Jacob Fugal