Problem Dynamically Loading a Module

Hi all,
I’m having some trouble with trying to dynamically load a module at runtime.
The following example demonstrates the problem I’m encountering.

dyninclude.rb

···

class DynamicInclude
def initialize(dynmod)
DynamicInclude.load_module(dynmod)
end

def DynamicInclude.load_module(modname)
load "#{modname}.rb"
include Object.const_get(modname.to_s)
end
end

Hello.rb

module Hello
def greeting
puts "Hello"
end
end

Goodbye.rb

module Goodbye
def greeting
puts "Goodbye"
end
end

Example

d = DynamicInclude.new(“Hello”)
d.greeting() # prints Hello
e = DynamicInclude.new(“Goodbye”)
e.greeting() # prints Goodbye
d.greeting() # prints Goodbye

So, how can I dynamically include multiple module without the negative side
effect of previous class instances inheriting the new methods? I’m suspecting
that the fact that load_module is a class method is playing a role here, but
I can’t make it work without making load_module a class method. Any help would
be appreciated.

Sincerely,
Travis Whitton whitton@atlantic.net

Try this

class DynamicInclude
  def initialize(dynmod)
    DynamicInclude.load_module(dynmod)

       extend(Object.const_get(dynmod.to_s))

  end

  def DynamicInclude.load_module(modname)
    load "#{modname}.rb"
    include Object.const_get(modname.to_s)

  you don't need this include

  end
end

Now if you are sure that these previous module don't exist you can write

svg% cat b.rb
#!/usr/bin/ruby

class DynamicInclude
   def initialize(dynmod)
      DynamicInclude.load_module(dynmod)
      extend(Object.instance_eval { remove_const(dynmod.to_s) })
   end

   def DynamicInclude.load_module(modname)
      load "#{modname}.rb"
   end
end

d = DynamicInclude.new("Hello")
d.greeting() # prints Hello
e = DynamicInclude.new("Goodbye")
e.greeting() # prints Goodbye
d.greeting() # prints Goodbye
svg%

svg% b.rb
Hello
Goodbye
Hello
svg%

The load is made in Object, then the constant is removed to don't pollute
Object

Guy Decoux

Guy,
Thanks very much! That solved my problem perfectly. I love the Ruby community.

Travis

···

In article 200309151635.h8FGZgT05555@moulon.inra.fr, ts wrote:

Try this

class DynamicInclude
def initialize(dynmod)
DynamicInclude.load_module(dynmod)

   extend(Object.const_get(dynmod.to_s))

end

def DynamicInclude.load_module(modname)
load “#{modname}.rb”
include Object.const_get(modname.to_s)

you don’t need this include

end
end

Now if you are sure that these previous module don’t exist you can write

svg% cat b.rb
#!/usr/bin/ruby

class DynamicInclude
def initialize(dynmod)
DynamicInclude.load_module(dynmod)
extend(Object.instance_eval { remove_const(dynmod.to_s) })
end

def DynamicInclude.load_module(modname)
load “#{modname}.rb”
end
end

d = DynamicInclude.new(“Hello”)
d.greeting() # prints Hello
e = DynamicInclude.new(“Goodbye”)
e.greeting() # prints Goodbye
d.greeting() # prints Goodbye
svg%

svg% b.rb
Hello
Goodbye
Hello
svg%

The load is made in Object, then the constant is removed to don’t pollute
Object

Guy Decoux