Forum: Ruby Dynamic class instantiation

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Jason (Guest)
on 2006-01-19 23:41
Hi all,

I have a situation where I need to dynamically execute an object from a
String name. I read in pickaxe that as long as a capitalize the class
name in the string, Ruby will see it as a Constant and thusly allow me
to use it.

For example:

module Test

  class MyClass
     def do_something
       puts "Something done."
     end
  end

end

(caller code)

cls = "Test::MyClass"
require cls
obj = cls.new
obj.do_something

------

When I execute the above caller code, I get an error saying

undefined method `new' for "Test::MyClass":String (NoMethodError)

So, obviously, Ruby is telling me that there is no new method for the
String "Test::MyClass". I'm trying to instantiate the class this way as
I have specific methods that return object besides String, so I'm
guessing eval(cls) isn't appropriate for me. Also, I checked the
archives on the list with no luck.

Any suggestions?

Thx,

- jason
unknown (Guest)
on 2006-01-19 23:50
(Received via mailing list)
On Fri, 20 Jan 2006, Jason wrote:

>
> cls = "Test::MyClass"
> So, obviously, Ruby is telling me that there is no new method for the
> String "Test::MyClass". I'm trying to instantiate the class this way as
> I have specific methods that return object besides String, so I'm
> guessing eval(cls) isn't appropriate for me. Also, I checked the
> archives on the list with no luck.
>
> Any suggestions?
>
> Thx,


     def klass_stamp(hierachy, *a, &b)
       ancestors = hierachy.split(%r/::/)
       parent = Object
       while((child = ancestors.shift))
         klass = parent.const_get child
         parent = klass
       end
       klass::new(*a, &b)
     end


     class A; class B;end; end

     klass_stamp 'A::B'

hth.

-a
Jason (Guest)
on 2006-01-19 23:59
unknown wrote:
>
>      def klass_stamp(hierachy, *a, &b)
>        ancestors = hierachy.split(%r/::/)
>        parent = Object
>        while((child = ancestors.shift))
>          klass = parent.const_get child
>          parent = klass
>        end
>        klass::new(*a, &b)
>      end
>
>
>      class A; class B;end; end
>
>      klass_stamp 'A::B'
>
> hth.
>
> -a

Actually, I just found this, which is a little simpler, but looks like
it does the same :)

mod = Module
name.split(/::/).each {|m| mod = mod.const_get(m) }
m = mod.new

# Call my method
m.do_something

Thx,

- jason
Eric H. (Guest)
on 2006-01-20 00:14
(Received via mailing list)
On Jan 19, 2006, at 1:23 PM, Jason wrote:

>>      end
> Actually, I just found this, which is a little simpler, but looks like
> it does the same :)
>
> mod = Module
> name.split(/::/).each {|m| mod = mod.const_get(m) }
> m = mod.new

def Object.path2class(path) # matches a C method that is not exported
into Ruby
   return path.split('::').inject(Object) { |k,n| k.const_get n }
end

m = Object.path2class('Test::MyClass').new

> # Call my method
> m.do_something

--
Eric H. - removed_email_address@domain.invalid - http://segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
This topic is locked and can not be replied to.