Dynamically require and include code in application

R

R. Kumar

I was hoping to dynamically load and include code in my application.
After some struggle, i've got this working. Wish to know if this is the
cleanest way to do so:

Since include has a problem (NoMethod) i tried making the method Class
level,
it works but include does not take a String, so eval it
Can this not be at instance level ??

def self.load_module requirename, includename
require "xxx/#{requirename}"
eval ( "include #{includename}")
end

I wish to call an initializer method in such a module which
will bind keys (for example)
needs to be done at object level


def init_module requirename, includename
send("#{requirename}_init") #if respond_to? "#{includename}_init"
end

I was hoping that the require and include could be at the instance
level, so other objects are not affected. Different objects (instances)
may include different modules.

I tried by NOT putting an include, just trying to call the methods using
send. I also appended the module name in the send, but got a no method
error.

The only other option i thought of was to extend my class and add this
functionlity but that obviously means too many extensions, I'd like
multiple modules to be loadable this way.
Thanks.
 
B

Brian Candler

R. Kumar said:
Since include has a problem (NoMethod)

What do you mean by this? Show your code.

Remember that 'include' has nothing to do with loading code. All it does
is make the methods of one module available in another class. Use
'require' to load code.

module Foo
def say_hello
puts "hello"
end
end

class Bar
include Foo
end

Bar.new.say_hello
i tried making the method Class
level,
it works but include does not take a String

include takes a Module. If you want to do it dynamically, use const_get.

include Object.const_get("Foo") # include ::Foo

include Wibble.const_get("Bar") # include Wibble::Bar
I was hoping that the require and include could be at the instance
level, so other objects are not affected.

Then maybe you want 'extend' rather than 'include'. 'extend' adds
instance methods from a module to a single object.

# with module Foo defined as above

a = "hello"
a.extend Foo
a.say_hello # says hello

b = "hello"
b.say_hello # NoMethodError

HTH,

Brian.
 
R

R. Kumar

Brian said:
include Object.const_get("Foo") # include ::Foo

Then maybe you want 'extend' rather than 'include'. 'extend' adds
instance methods from a module to a single object.

# with module Foo defined as above

a = "hello"
a.extend Foo
a.say_hello # says hello
HTH,

Brian.

Just what i wanted, Brian. Now its just an instance method:

def load_module requirename, includename
require "mylib/#{requirename}"

extend Object.const_get("#{includename}")
send("#{requirename}_init")
end

I guess i could just lowercase the includename and have param. Thanks a
million.
 
B

Brian Candler

R. Kumar said:
Just what i wanted, Brian. Now its just an instance method:

def load_module requirename, includename
require "mylib/#{requirename}"

extend Object.const_get("#{includename}")
send("#{requirename}_init")
end

Slight simplification: extend Object.const_get(includename)

(There's no need for string interpolation on that line; const_get will
take either a symbol or a string)
I guess i could just lowercase the includename and have param.

That's how Rails handles it: use conventions to convert filenames to
module/class names and vice versa.
=> true
=> "FooBar"
=> "Foo::Bar"
 

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,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top