Dynamically require and include code in application

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.

···

--
Posted via http://www.ruby-forum.com/.

R. Kumar wrote:

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.

···

--
Posted via http://www.ruby-forum.com/\.

Brian Candler wrote:

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.

···

--
Posted via http://www.ruby-forum.com/\.

R. Kumar wrote:

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.

require 'rubygems'

=> true

require 'activesupport'

=> true

"FooBar".underscore

=> "foo_bar"

"foo_bar".camelize

=> "FooBar"

"Foo::Bar".underscore

=> "foo/bar"

"foo/bar".camelize

=> "Foo::Bar"

···

--
Posted via http://www.ruby-forum.com/\.