Dumb reflection problem - create object from String


#1

Hello - I’m bashing my head against the wall - I’m sure this is a simple
question, but damned if I can figure it out.

If I have a String which corresponds to a class name, how do I create an
instance of this class?

Example:

class MyExampleClass

end

s = ‘MyExampleClass’

We want to instantiate a new instance of the class

myExampleClassInstance = ???

I want the behaviour of ‘MyExampleClass.new’ but only using the String
value of s.

I’m sure it’s a one-liner.

Any help appreciated.

Thanks.

parki…


#2

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Brian P. wrote:

end

s = ‘MyExampleClass’

We want to instantiate a new instance of the class

myExampleClassInstance = ???

I want the behaviour of ‘MyExampleClass.new’ but only using the String
value of s.

Have a look at Module.const_get

Module.const_get(s).new

HTH,
Sven

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (FreeBSD)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFEOVItevlgTHEIT4YRAl3wAJ4j4zJTlcMR9A8ZJKixHXvig0eGywCfUPGN
W26rak8DMs/szMC+niiVvds=
=8+ZL
-----END PGP SIGNATURE-----


#3

On 4/10/06, Brian P. removed_email_address@domain.invalid wrote:

end

$ irb
irb(main):001:0> class K
irb(main):002:1> end
=> nil
irb(main):003:0> k1 = K.new
=> #<K:0xb7fc1788>
irb(main):004:0> k2 = eval(‘K’).new
=> #<K:0xb7fb8094>
irb(main):005:0> k3 = Object.const_get(‘K’).new
=> #<K:0xb7fb1474>


#4

Sven K. wrote:

[deletia]

Module.const_get(s).new

Thanks!

I knew it would be a one-liner. :slight_smile:

parki…


#5

DÅ?a Nedeľa 9. Apríl 2006 20:26 Gyoung-Yoon N. napísal:

...

I’m sure it’s a one-liner.


http://nohmad.sub-port.net

I would, naively hoping to see YARV released Sometime Soon ™, rather
use
, since it probably is / will be easier for YARV to
work
with , as far as optimizations are concerned. It also
makes the intent of the code clearer.

David V.


#6

On 4/9/06, Brian P. removed_email_address@domain.invalid wrote:

parki…

I am afraid that the only one-liner is eval :frowning:

suppose s contains the name of your class
Module.const_get s does not work unless your class is defined on top
level.
In oder to have the same semantics as

eval(s).new

we have to write

m = Module
s.split(%r{::|.}).each do
|name|
m = m.const_get(name)
end
m.new

I suggest to look at ObjectSpace for another alternative, hardly more
efficent though :frowning:

Robert


Deux choses sont infinies : l’univers et la bêtise humaine ; en ce qui
concerne l’univers, je n’en ai pas acquis la certitude absolue.

  • Albert Einstein

#7

On Apr 9, 2006, at 3:21 PM, Robert D. wrote:

I knew it would be a one-liner. :slight_smile:

  • Albert Einstein
    s.split(/::/).inject(Object) { |p, c| p.const_get© }.new

There, a one liner (w/o any semi-colons)


#8

Robert D. wrote:

On 4/9/06, Brian P. removed_email_address@domain.invalid wrote:

parki…

I am afraid that the only one-liner is eval :frowning:

suppose s contains the name of your class
Module.const_get s does not work unless your class is defined on top
level.
In oder to have the same semantics as

eval(s).new

we have to write

m = Module
s.split(%r{::|.}).each do
|name|
m = m.const_get(name)
end
m.new

s.split(’::’).inject(Object) { |s,k| s.const_get(k) }.new

– Jim W.


#9

On 4/9/06, Logan C. removed_email_address@domain.invalid wrote:

Module.const_get(s).new
suppose s contains the name of your class
|name|

Yup, very nice
What I meant though is that eval seems much simpler and cheaper
Let us see
yet your’s is fine, just look at the mess when searching through
ObjectSpace

cat perf.rb; ruby perf.rb
require ‘benchmark’

module One
class Two
class Three
end
end
end
s=“One::two::Three”
n = 50000
Benchmark.bm do |x|
x.report("eval "){ n.times{ eval(s).new } }
x.report("split ") { n.times{ s.split(/::/).inject(Object) { |p,
c|
p.const_get© }.new } }
x.report(“ObjectSpace”){n.times{x=nil;ObjectSpace.each_object(Class){|cls|
x=cls if
cls.to_s == s};x.new } }
end user system total real
eval 0.280000 0.000000 0.280000 ( 0.372346)
split 0.540000 0.000000 0.540000 ( 0.621870)
ObjectSpace 21.920000 0.070000 21.990000 ( 24.452318)


Deux choses sont infinies : l’univers et la bêtise humaine ; en ce qui
concerne l’univers, je n’en ai pas acquis la certitude absolue.

  • Albert Einstein