get a class from its name

R

Rolando Abarca

--Apple-Mail-14-1040847564
Content-Type: multipart/alternative; boundary=Apple-Mail-13-1040847532


--Apple-Mail-13-1040847532
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
delsp=yes;
format=flowed

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,
--
Rolando Abarca
Phone: +56-9 97851962



--Apple-Mail-13-1040847532
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
charset=ISO-8859-1

<HTML><BODY style=3D"word-wrap: break-word; -khtml-nbsp-mode: space; =
-khtml-line-break: after-white-space; ">This is how i'm currently =
getting a class object from a name:<DIV><BR =
class=3D"khtml-block-placeholder"></DIV><DIV>=A0 =A0 =A0=A0 =A0cname =3D =
"A::B::C::D"</DIV><DIV>=A0 =A0 =A0 =A0 klass =3D =
cname.split("::").inject(Kernel) {|a,b| a.const_get(b)}</DIV><DIV><BR =
class=3D"khtml-block-placeholder"></DIV><DIV>I think it's pretty =
elegant, but I'm always happy to hear other ways to do it =
;-)</DIV><DIV>Anyone does this in some other way? (I don't want to eval =
code...)</DIV><DIV><BR =
class=3D"khtml-block-placeholder"></DIV><DIV>regards,<BR><DIV> <SPAN =
class=3D"Apple-style-span" style=3D"border-collapse: separate; =
border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; =
font-size: 12px; font-style: normal; font-variant: normal; font-weight: =
normal; letter-spacing: normal; line-height: normal; text-align: auto; =
-khtml-text-decorations-in-effect: none; text-indent: 0px; =
-apple-text-size-adjust: auto; text-transform: none; orphans: 2; =
white-space: normal; widows: 2; word-spacing: 0px; =
"><DIV>--=A0</DIV><DIV>Rolando Abarca</DIV><DIV>Phone: +56-9 =
97851962</DIV><BR class=3D"Apple-interchange-newline"></SPAN> =
</DIV><BR></DIV></BODY></HTML>=

--Apple-Mail-13-1040847532--

--Apple-Mail-14-1040847564
content-type: application/pgp-signature; x-mac-type=70674453;
name=PGP.sig
content-description: This is a digitally signed message part
content-disposition: inline; filename=PGP.sig
content-transfer-encoding: 7bit

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)

iD8DBQFGyilJ9fOunnYODS4RAlCRAJ9+rHn8mKVgVJnoDKmPdj+8Lqt3pgCdEzC8
Wbn/cE7kM/vdADtf9+Wwd60=
=/+qj
-----END PGP SIGNATURE-----

--Apple-Mail-14-1040847564--
 
S

Sam Smoot

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,
--
Rolando Abarca
Phone: +56-9 97851962

PGP.sig
1KDownload

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

David A. Black

Hi --

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

--
* Books:
RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
RUBY FOR RAILS (http://www.manning.com/black)
* Ruby/Rails training
& consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
 
T

Tim Pease

Hi --



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::B::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
 
D

David A. Black

Hi --

"A::B::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.

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

--
* Books:
RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
RUBY FOR RAILS (http://www.manning.com/black)
* Ruby/Rails training
& consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
 
R

Robert Klemme

2007/8/21 said:
Hi --



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.

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::B::C".split("::").inject(Kernel) {|a,b| a.const_get(b)}
=> A::B::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::B::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::B::C"
=> A::B::C
irb(main):028:0> module A
irb(main):029:1> p deref("B::C")
irb(main):030:1> p deref("::A::B")
irb(main):031:1> end
A::B::C
A::B
=> nil


Kind regards

robert
 
R

Rolando Abarca

--Apple-Mail-2--1049888971
Content-Type: multipart/alternative; boundary=Apple-Mail-1--1049889042


--Apple-Mail-1--1049889042
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
delsp=yes;
format=flowed

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 :)

regards,
--
Rolando Abarca
Phone: +56-9 97851962



--Apple-Mail-1--1049889042
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
charset=ISO-8859-1

<HTML><BODY style=3D"word-wrap: break-word; -khtml-nbsp-mode: space; =
-khtml-line-break: after-white-space; "><DIV><DIV>On Aug 21, 2007, at =
10:41 AM, Robert Klemme wrote:</DIV><BR =
class=3D"Apple-interchange-newline"><BLOCKQUOTE type=3D"cite"><DIV =
style=3D"margin-top: 0px; margin-right: 0px; margin-bottom: 0px; =
margin-left: 0px; ">Definitively.</DIV><DIV style=3D"margin-top: 0px; =
margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: =
14px; "><BR></DIV><DIV style=3D"margin-top: 0px; margin-right: 0px; =
margin-bottom: 0px; margin-left: 0px; ">Folks, please keep in mind that =
the proposed solution from the OP's</DIV><DIV style=3D"margin-top: 0px; =
margin-right: 0px; margin-bottom: 0px; margin-left: 0px; ">posting works =
only in the global context:</DIV></BLOCKQUOTE><DIV><BR =
class=3D"khtml-block-placeholder"></DIV><DIV>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 :)</DIV><BR><BLOCKQUOTE type=3D"cite"><DIV =
style=3D"margin-top: 0px; margin-right: 0px; margin-bottom: 0px; =
margin-left: 0px; ">robert</DIV></BLOCKQUOTE></DIV><DIV><BR =
class=3D"khtml-block-placeholder"></DIV>regards,<BR><DIV> <SPAN =
class=3D"Apple-style-span" style=3D"border-collapse: separate; =
border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; =
font-size: 12px; font-style: normal; font-variant: normal; font-weight: =
normal; letter-spacing: normal; line-height: normal; text-align: auto; =
-khtml-text-decorations-in-effect: none; text-indent: 0px; =
-apple-text-size-adjust: auto; text-transform: none; orphans: 2; =
white-space: normal; widows: 2; word-spacing: 0px; =
"><DIV>--=A0</DIV><DIV>Rolando Abarca</DIV><DIV>Phone: +56-9 =
97851962</DIV><BR class=3D"Apple-interchange-newline"></SPAN> =
</DIV><BR></BODY></HTML>=

--Apple-Mail-1--1049889042--

--Apple-Mail-2--1049888971
content-type: application/pgp-signature; x-mac-type=70674453;
name=PGP.sig
content-description: This is a digitally signed message part
content-disposition: inline; filename=PGP.sig
content-transfer-encoding: 7bit

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)

iD8DBQFGywb09fOunnYODS4RAst6AJwPwHP3QrQtz9as4sp9jvC5ukx1cgCgxpj1
Yr3h73EAM5QuNf9xrLHTKWU=
=V8Tq
-----END PGP SIGNATURE-----

--Apple-Mail-2--1049888971--
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,998
Messages
2,570,242
Members
46,834
Latest member
vina0631

Latest Threads

Top