Forum: Ruby Intantiating a class by name

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.
Erich L. Timkar (Guest)
on 2006-05-10 08:32
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
Ola B. (Guest)
on 2006-05-10 08:42
(Received via mailing list)
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" <removed_email_address@domain.invalid>
Date: Wednesday, May 10, 2006 6:32 am
Subject: Intantiating a class by name
To: removed_email_address@domain.invalid (ruby-talk ML)
Jake McArthur (Guest)
on 2006-05-10 08:45
(Received via mailing list)
class Foo
   # stuff
end

bar = Kernel.const_get("Foo").new

- Jake McArthur
Ryan L. (Guest)
on 2006-05-10 09:06
(Received via mailing list)
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
unknown (Guest)
on 2006-05-10 12:06
(Received via mailing list)
> 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
unknown (Guest)
on 2006-05-10 13:28
(Received via mailing list)
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
Daniel S. (Guest)
on 2006-05-10 16:15
(Received via mailing list)
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
Daniel S. (Guest)
on 2006-05-10 16:33
(Received via mailing list)
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
Logan C. (Guest)
on 2006-05-10 16:49
(Received via mailing list)
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.
Daniel H. (Guest)
on 2006-05-10 16:55
(Received via mailing list)
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
Daniel S. (Guest)
on 2006-05-10 17:54
(Received via mailing list)
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
Erich L. Timkar (Guest)
on 2006-05-11 04:18
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.
This topic is locked and can not be replied to.