Intantiating a class by name

For the life of me I haven’t been able to find the syntax to
“instatiate” a class given it’s name. I know it’s silly. I feel silly
and when I hear the answer, I’ll fill twice as silly. Anyone wanna take
a stab at this and put me out of my misery?

erich

Hi.

Say that you get a String like “A::b::C” and would like this
instantiated:

obj_class = Object
name.split( “::” ).each { |c| obj_class = obj_class.const_get( c ) } if
name
o = obj_class.new

Regards
Ola B.

----- Original Message -----
From: “Erich L. Timkar” [email protected]
Date: Wednesday, May 10, 2006 6:32 am
Subject: Intantiating a class by name
To: [email protected] (ruby-talk ML)

class Foo

stuff

end

bar = Kernel.const_get(“Foo”).new

  • Jake McArthur

No offense to the OP, but this is about the 5th time this has been
asked by Ruby Forum users in the last few weeks. Ruby Forum REALLY,
REALLY needs a FAQ with answers to questions like this.

FYI all Ruby Forum users: when you ask your questions they are sent
not just to Ruby Forum but to the ruby-talk mailing list, which has
probably thousands of subscribers.

Ryan

I’m renaming and resending this post. I should have branched the
inappropriate subject when I first made my posting, sorry.

Sumary: Some questions come up regularly on the list. A wiki for answers
would be a superb resource. How about using:

http://www.rubygarden.org/ruby?QuestionsAndAnswers

No offense to the OP, but this is about the 5th time this has been
asked by Ruby Forum users in the last few weeks. Ruby Forum REALLY,
REALLY needs a FAQ with answers to questions like this.

The Ruby Garden has a list of questions like this:

http://www.rubygarden.org/ruby?QuestionsAndAnswers

Specifically, this exact question is addressed:

http://www.rubygarden.org/ruby?FindClassesByName

[Brief discussion, and then two solutions for the the general case,
including an “inject” implementation.]

It’s been previously suggested that when questions like this are asked,
and good answers are given, they should be collected. This seems to be
an ideal location for such a catalogue. There are not too many answers
there yet (a dozen, or so). Perhaps in the future, more indexing would
be needed, but it looks ideal for now.

Cheers,
Benjohn

Daniel S. wrote:

Isn’t it more appropriate to call #to_str on `name’? I.e.
name.to_str.split(…

Come to think of it, Symbol doesn’t define #to_str, so maybe this is
better:

name.to_sym.to_str.split(…

Furthermore, defining it in Module as a replacement for #const_get makes
sense, since they do the same thing, our version is just smarter:

class Module
alias_method :old_const_get, :const_get
def const_get(str)
names = str.to_sym.to_s.split(’::’)
names.inject(self){|parent, child| parent.old_const_get(child) }
end
end

class A; class B; class C; end; end; end

A.const_get :B => A::B
A::B.const_get :C => A::b::C
A.const_get “B::C” => A::b::C
Kernel.const_get “A::b::C” => A::b::C

Cheers,
Daniel

Erich L. Timkar wrote:

For the life of me I haven’t been able to find the syntax to
“instatiate” a class given it’s name. I know it’s silly. I feel silly
and when I hear the answer, I’ll fill twice as silly. Anyone wanna take
a stab at this and put me out of my misery?

As the other guys have said, RubyGarden have the following
implementation:

def get_class(name)
name.split(/::/).inject{|parent, child| parent.const_get(child) }
end

I actually have two questions regarding this implementation:

  1. Is /::/' faster than“::”’?
  2. Isn’t it more appropriate to call #to_str on `name’? I.e.
    name.to_str.split(…

Cheers,
Daniel

On May 10, 2006, at 6:32 AM, Erich L. Timkar wrote:

For the life of me I haven’t been able to find the syntax to
“instatiate” a class given it’s name. I know it’s silly. I feel
silly
and when I hear the answer, I’ll fill twice as silly. Anyone wanna
take
a stab at this and put me out of my misery?

class Foo; end

def make_new(klass)
klass.new
end

make_new(Foo) # => #Foo:0x2c4f4

Classes and modules are constants. If you have a string containing
the class/module name use the inject+const_get solution.

– Daniel

On May 10, 2006, at 8:32 AM, Daniel S. wrote:

Come to think of it, Symbol doesn’t define #to_str, so maybe this
is better:

name.to_sym.to_str.split(…

You’re right it doesn’t, so how does explicitly converting name into
a symbol and then calling to_str help?

Ah nevermind I see from your code this was probably a typo. Then
riddle me this, why the double conversion?

to_sym.to_s should just be squished into to_s.

I appreciate the array of options expressed on this. It really has
given a good perspective on my question. I guess I’ll do a more
extensive search on this issue, next time. Sorry to fill up your in
box.

Logan C. wrote:

Ah nevermind I see from your code this was probably a typo.

Yup, it was supposed to read `to_sym.to_s’

Then riddle me this, why the double conversion?

to_sym.to_s should just be squished into to_s.

It may just be my own preference, but I think it’s nice to restrict the
`types’ of arguments a method can take – not by class, but by defined
methods. So when you say that #get_const takes a symbol as an argument,
you know you can give it every object that responds to #to_sym.

But yes, #to_s could be used.

Cheers,
Daniel