choosing a module name at runtime

J

John Smirnoff

My application chooses at runtime the input format of some data, for
example :xml or :mysql. Then, the app instantiates a DataManager. The
DataManager class should 'include' the appropriate Module (either
DataIOXML or DataIOMySQL).
I tried to use include in the initialize method of DataManager, but that
doesn't work.
Can I include a module in the initialize method of the class? If yes,
how?
If no: Any other ways how I can choose the correct module to include at
runtime?

Important: All the information about Modules and file names is stored in
the DataManager class. My app only knows the DataManger class itself,
not the names of the modules (so I can't subclass separate IO classes
from DataManager, and instantiate them directly from my app).

Here's the example code for the app, the DataManger class, and the :xml
Module:



#! /usr/bin/ruby -w
# main app
#
# here, only the name 'DataManager' and the IO format :)xml or :mysql)
is known,
# not the name of the format-specific module.
require "DataManager.rb"
dm = DataManager.new:)xml)
dm.say_something



# DataManager.rb
class DataManager

# theDataManager class knows all possible IO formats, and the
# corresponding Module names:
@@io_mixins = {
:xml => 'DataIOXML',
:mysql => 'DataIOMySQL',
}

def initialize(format=:xml)

unless @@io_mixins.include? format
raise NotImplementedError, "IO Format #{format} unknown"
end

require @@io_mixins[format]+".rb"
# the next line causes an error
include DataIOXML

end
end



# DataIOXML.rb
# XML-specific module
module DataIOXML
def say_something
puts "I'm DataIOXML"
end
end
 
A

Aaron Patterson

My application chooses at runtime the input format of some data, for
example :xml or :mysql. Then, the app instantiates a DataManager. The
DataManager class should 'include' the appropriate Module (either
DataIOXML or DataIOMySQL).
I tried to use include in the initialize method of DataManager, but
that
doesn't work.
Can I include a module in the initialize method of the class? If yes,
how?
If no: Any other ways how I can choose the correct module to include
at
runtime?

You want the "extend" method, not the "include" method:

module A
def foo
"A: foo"
end
end

module B
def foo
"B: foo"
end
end

class C
def initialize which
extend(which == :a ? A : B)
end

def metaclass; class << self; self end end
end

p C.new:)a).metaclass.ancestors
p C.new:)b).metaclass.ancestors

Hope that helps.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top