From: Hagbard Celine on
Hey folks!

In my current project I try to load a module dynamically. Which is
basically no problem due to 'require` accepting filenames as well. My
problem is that I'd totally pollute my namespace. I thought of something
like the following:

def load_module(filename)
module NamespaceGuard # Just a random name
require filename
# Take a care of the loaded module
end
# My namespace is clean again
end

But Ruby's syntax apparently forbids module definitions in methods. I'd
be very glad if anyone could help me with this problem.
--
Posted via http://www.ruby-forum.com/.

From: Intransition on


On Jun 13, 2:33 pm, Hagbard Celine <sin3141...(a)gmail.com> wrote:
> Hey folks!
>
> In my current project I try to load a module dynamically. Which is
> basically no problem due to 'require` accepting filenames as well. My
> problem is that I'd totally pollute my namespace. I thought of something
> like the following:
>
> def load_module(filename)
>   module NamespaceGuard  # Just a random name
>     require filename
>     # Take a care of the loaded module
>   end
>   # My namespace is clean again
> end
>
> But Ruby's syntax apparently forbids module definitions in methods. I'd
> be very glad if anyone could help me with this problem.

Usually the file you are loading has the "protective" namespace. Eg.

# namespace_guard.rb
module NamespaceGuard
...
end

# main.rb
require 'namespace_guard'


From: Joel VanderWerf on
Hagbard Celine wrote:
> Hey folks!
>
> In my current project I try to load a module dynamically. Which is
> basically no problem due to 'require` accepting filenames as well. My
> problem is that I'd totally pollute my namespace. I thought of something
> like the following:
>
> def load_module(filename)
> module NamespaceGuard # Just a random name
> require filename
> # Take a care of the loaded module
> end
> # My namespace is clean again
> end
>
> But Ruby's syntax apparently forbids module definitions in methods. I'd
> be very glad if anyone could help me with this problem.

You certainly can define modules dynamically:

def make_mod
Module.new do
def self.foo; p "FOO"; end
def bar; p "BAR"; end
end
end

m = make_mod

p m.methods(false) # ==> ["foo"]
p m.instance_methods(false) # ==> ["bar"]

m.foo # ==> "FOO"
x=[]
x.extend m
x.bar # ==> "BAR"

Also,, the #load method takes an optional argument that causes it to
wrap the loaded definitions in

$ ri Kernel#load | cat
------------------------------------------------------------ Kernel#load
load(filename, wrap=false) => true
------------------------------------------------------------------------
Loads and executes the Ruby program in the file filename. If the
filename does not resolve to an absolute path, the file is
searched for in the library directories listed in $:. If the
optional wrap parameter is true, the loaded script will be
executed under an anonymous module, protecting the calling
program's global namespace. In no circumstance will any local
variables in the loaded file be propagated to the loading
environment.

You can use this like so:

$ cat b.rb
def foo
puts "foo in b"
end

$ cat a.rb
load "b.rb", true # try this without the true

begin
foo
rescue => e
puts e
end

def foo
puts "foo in a"
end

foo

$ ruby a.rb
undefined local variable or method `foo' for main:Object
foo in a


However, you don't get easy access to the anonymous module. If you want
that, I have a little library that may be helpful:

http://redshift.sourceforge.net/script/



From: Brian Candler on
Hagbard Celine wrote:
> In my current project I try to load a module dynamically. Which is
> basically no problem due to 'require` accepting filenames as well. My
> problem is that I'd totally pollute my namespace.

Kernel.load(filename, true) might help. But AFAIK that doesn't prevent
the source code from doing

class ::Object
def override_something_important
..
end
end

If you need to protect against untrusted code, have a look at _why's
sandbox.
--
Posted via http://www.ruby-forum.com/.

From: Rein Henrichs on
Kernel#require does not namespace anything, no matter how you use it.

Properly written Rubby libraries namespace their classes and modules.
If you own the code you're requiring, fix it. If not, find an
alternative to the code in question (which I find suspect based on this
lack of namespacing) or perhaps you may find some luck with Kernel#load.


--
Rein Henrichs
http://puppetlabs.com
http://reinh.com