# Get a class from its name

**URL:** <https://www.ruby-forum.com/t/get-a-class-from-its-name/112578>\
**Category:** Ruby\
**Created:** [August 21, 2007, 2:17am UTC](https://www.ruby-forum.com/t/get-a-class-from-its-name/112578 "2007-08-21T02:17:44Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rolando\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/d9b06d/32.png) [@Rolando\_A](https://www.ruby-forum.com/u/Rolando_A)\
**Post date:** [August 21, 2007, 2:17am UTC](https://www.ruby-forum.com/t/get-a-class-from-its-name/112578/1 "2007-08-21T02:17:44Z")

</div>

This is how i’m currently getting a class object from a name:

```
     cname = "A::B::C::D"
     klass = cname.split("::").inject(Kernel) {|a,b| a.const_get(b)}

```

I think it’s pretty elegant, but I’m always happy to hear other ways  
to do it 😉  
Anyone does this in some other way? (I don’t want to eval code…)

regards,

---

<div class="post-metadata">

**Author:** ![Rolando\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/d9b06d/32.png) [@Rolando\_A](https://www.ruby-forum.com/u/Rolando_A)\
**Post date:** [August 21, 2007, 2:51am UTC](https://www.ruby-forum.com/t/get-a-class-from-its-name/112578/2 "2007-08-21T02:51:49Z")

</div>

On Aug 20, 7:16 pm, Rolando A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> –  
> Rolando A.  
> Phone: +56-9 97851962
> 
> PGP.sig  
> 1KDownload

I’ve seen little helper methods for this, but never so elegant. Nice!

---

<div class="post-metadata">

**Author:** ![Rolando\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/d9b06d/32.png) [@Rolando\_A](https://www.ruby-forum.com/u/Rolando_A)\
**Post date:** [August 21, 2007, 3:42am UTC](https://www.ruby-forum.com/t/get-a-class-from-its-name/112578/3 "2007-08-21T03:42:54Z")

</div>

Hi –

On Tue, 21 Aug 2007, Rolando A. wrote:

> This is how i’m currently getting a class object from a name:
> 
> ```
> cname = "A::B::C::D"
> klass = cname.split("::").inject(Kernel) {|a,b| a.const_get(b)}
> 
> ```
> 
> I think it’s pretty elegant, but I’m always happy to hear other ways to do it  
> 😉  
> Anyone does this in some other way? (I don’t want to eval code…)

I think it’s usually done the way you’ve got it there. It’s one of  
those things that people write over and over (like map\_with\_index and  
singleton\_method), hopefully some day to enter the core as  
const\_get\_deep or something.

David

---

<div class="post-metadata">

**Author:** ![Rolando\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/d9b06d/32.png) [@Rolando\_A](https://www.ruby-forum.com/u/Rolando_A)\
**Post date:** [August 21, 2007, 1:43pm UTC](https://www.ruby-forum.com/t/get-a-class-from-its-name/112578/4 "2007-08-21T13:43:03Z")

</div>

Hi –

On Tue, 21 Aug 2007, Tim P. wrote:

> > > I think it’s pretty elegant, but I’m always happy to hear other ways to do it
> 
> It could just be a wrapper for the core method rb\_path2class – which  
> does the same thing in Ruby C API land.

It’s a more general-purpose thing, though; it’s for any constant, not  
just classes. It’s really just a variation on const\_get, which already  
will give you any constant from any existing class/module nesting.

David

---

<div class="post-metadata">

**Author:** ![Rolando\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/d9b06d/32.png) [@Rolando\_A](https://www.ruby-forum.com/u/Rolando_A)\
**Post date:** [August 21, 2007, 4:42pm UTC](https://www.ruby-forum.com/t/get-a-class-from-its-name/112578/5 "2007-08-21T16:42:48Z")

</div>

2007/8/21, David A. Black [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> will give you any constant from any existing class/module nesting.  
> Definitively.

Folks, please keep in mind that the proposed solution from the OP’s  
posting works only in the global context:

irb(main):001:0\> module A  
irb(main):002:1\> module B  
irb(main):003:2\> module C  
irb(main):004:3\> end  
irb(main):005:2\> end  
irb(main):006:1\> end  
=\> nil  
irb(main):007:0\> “A:🅱:C”.split(“::”).inject(Kernel) {|a,b|  
a.const\_get(b)}  
=\> A:🅱:C  
irb(main):008:0\> module A  
irb(main):009:1\> p “B::C”.split(“::”).inject(Kernel) {|a,b|  
a.const\_get(b)}  
irb(main):010:1\> end  
NameError: uninitialized constant Kernel::B  
from (irb):9:in `const_get' from (irb):9 from (irb):10:in `inject’  
from (irb):9:in `each' from (irb):9:in `inject’  
from (irb):9  
from :0  
irb(main):011:0\> module A  
irb(main):012:1\> p “B::C”.split(“::”).inject(self) {|a,b|  
a.const\_get(b)}  
irb(main):013:1\> end  
A:🅱:C  
=\> nil

There needs to be at least a bit more logic to take care of nested  
scopes and constants with leading “::”. Having said that it’s probably  
wise to put the method in class Module, like:

class Module  
def deref(name)  
parts = name.split “::”  
start = self

```
if parts.first == ""
  # start with global scope
  start = Kernel
  parts.shift
end

parts.inject(start) {|a,b| a.const_get(b)}

```

end  
end

class Object  
def deref(name)  
self.class.deref(name)  
end  
end

irb(main):021:0\> module A  
irb(main):022:1\> module B  
irb(main):023:2\> module C  
irb(main):024:3\> end  
irb(main):025:2\> end  
irb(main):026:1\> end  
=\> nil  
irb(main):027:0\> deref “A:🅱:C”  
=\> A:🅱:C  
irb(main):028:0\> module A  
irb(main):029:1\> p deref(“B::C”)  
irb(main):030:1\> p deref(“:🅰:B”)  
irb(main):031:1\> end  
A:🅱:C  
A::B  
=\> nil

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![Rolando\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/d9b06d/32.png) [@Rolando\_A](https://www.ruby-forum.com/u/Rolando_A)\
**Post date:** [August 21, 2007, 4:44am UTC](https://www.ruby-forum.com/t/get-a-class-from-its-name/112578/6 "2007-08-21T04:44:59Z")

</div>

On 8/20/07, David A. Black [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > 😉  
> > Anyone does this in some other way? (I don’t want to eval code…)
> 
> I think it’s usually done the way you’ve got it there. It’s one of  
> those things that people write over and over (like map\_with\_index and  
> singleton\_method), hopefully some day to enter the core as  
> const\_get\_deep or something.

“A:🅱:C::D”.to\_class

It could just be a wrapper for the core method rb\_path2class – which  
does the same thing in Ruby C API land.

Blessings,  
TwP

---

<div class="post-metadata">

**Author:** ![Rolando\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/d9b06d/32.png) [@Rolando\_A](https://www.ruby-forum.com/u/Rolando_A)\
**Post date:** [August 21, 2007, 5:39pm UTC](https://www.ruby-forum.com/t/get-a-class-from-its-name/112578/7 "2007-08-21T17:39:03Z")

</div>

On Aug 21, 2007, at 10:41 AM, Robert K. wrote:

> Definitively.
> 
> Folks, please keep in mind that the proposed solution from the OP’s  
> posting works only in the global context:

Ok… I get your point. It’s not a general dereferencer, i mean, it  
doesn’t take the current scope and figure it outs the name from  
there, it always assume the string is the full path… Maybe what you  
propose could be the general solution to the deref problem 🙂

> robert

regards,

---

<div class="post-metadata">

**Author:** ![Rolando\_A](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/d9b06d/32.png) [@Rolando\_A](https://www.ruby-forum.com/u/Rolando_A)\
**Post date:** [August 21, 2007, 4:43pm UTC](https://www.ruby-forum.com/t/get-a-class-from-its-name/112578/8 "2007-08-21T16:43:49Z")

</div>

On Aug 20, 2007, at 20:16 , Rolando A. wrote:

> This is how i’m currently getting a class object from a name:
> 
> ```
> cname = "A::B::C::D"
> klass = cname.split("::").inject(Kernel) {|a,b| a.const_get 
> 
> ```
> 
> (b)}
> 
> I think it’s pretty elegant, but I’m always happy to hear other  
> ways to do it 😉  
> Anyone does this in some other way? (I don’t want to eval code…)

I use pretty much the same thing:

class String  
def const\_get  
self.split( “::” ).inject( Kernel ) { | parent, child |  
parent.const\_get( child ) }  
end  
end

# Example

module A  
class B  
C = ‘c’  
end  
end

> > “A”.const\_get  
> > =\> A

> > “A::B”.const\_get  
> > =\> A::B

> > “A:🅱:C”.const\_get  
> > =\> “c”

~Wayne

s///g  
Wayne E. Seguin  
Sr. Systems Architect & Systems Administrator
