Creating an instance of a class in a module through a string

Let's say I have this Ruby code in test.rb

module MyModule class TestClassA end class TestClassB def initialize a = Object.const_get('MyModule::TestClassA').new end end end 

Here, some tests in the ruby ​​shell started with irb -r test.rb:

 ruby-1.8.7-p302 > MyModule => MyModule ruby-1.8.7-p302 > MyModule::TestClassA => MyModule::TestClassA ruby-1.8.7-p302 > MyModule::TestClassA.new => #<MyModule::TestClassA:0x10036bef0> ruby-1.8.7-p302 > MyModule::TestClassB => MyModule::TestClassB ruby-1.8.7-p302 > MyModule::TestClassB.new NameError: wrong constant name MyModule::TestClassA from ./test.rb:7:in `const_get' from ./test.rb:7:in `initialize' from (irb):1:in `new' from (irb):1 

Why Object.const_get('MyModule::TestClassA').new in the TestClassB constructor not work, and MyModule::TestClassA.new works in the console? I also tried Object.const_get('TestClassA').new , but this does not work either.

+7
source share
3 answers

There is no constant with the name "MyModule :: TestClassA", there is a constant with the name TestClassA inside the constant with the name MyModule.

Try:

 module MyModule class TestClassA end class TestClassB def initialize a = Object.const_get("MyModule").const_get("TestClassA").new end end end 

As for why this doesn't work, this is because :: is an operator, not a naming convention.

Additional examples and information are available at http://www.ruby-forum.com/topic/182803

+17
source

In Ruby 2.0+, this works fine:

 #! /usr/bin/env ruby module Foo class Bar def initialize(baz) @baz = baz end def qux puts "quux: #{@baz}" end end end Kernel.const_get("Foo::Bar").new('corge').qux 

Results:

 bash-3.2$ ./test.rb quux: corge 
0
source

I think you can use Object.const_get :

 klass = Object.const_get "ClassName" klass.new 
0
source

All Articles