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/\.