Dumb reflection problem - create object from String

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...

···

--
Posted via http://www.ruby-forum.com/.

Brian Parkinson wrote:

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.

Have a look at Module.const_get

Module.const_get(s).new

HTH,
Sven

$ 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>

···

On 4/10/06, Brian Parkinson <parkI@whatevernot.com> wrote:

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...

--
Posted via http://www.ruby-forum.com/\.

--
http://nohmad.sub-port.net

Sven Klemm wrote:

[deletia]

Module.const_get(s).new

Thanks!

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

parki...

···

--
Posted via http://www.ruby-forum.com/\.

Dňa Nedeľa 9. Apríl 2006 20:26 Gyoung-Yoon Noh napísal:

···

On 4/10/06, Brian Parkinson <parkI@whatevernot.com> wrote:
> 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...
>
>
> --
> Posted via http://www.ruby-forum.com/\.

$ 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>

--
http://nohmad.sub-port.net

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

David Vallner

Sven Klemm wrote:

[deletia]

> Module.const_get(s).new

Thanks!

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

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

···

On 4/9/06, Brian Parkinson <parkI@whatevernot.com> wrote:

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

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

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

···

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

On 4/9/06, Brian Parkinson <parkI@whatevernot.com> wrote:

Sven Klemm wrote:

[deletia]

Module.const_get(s).new

Thanks!

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

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

Robert Dober wrote:

···

On 4/9/06, Brian Parkinson <parkI@whatevernot.com> 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 Weirich

--
Posted via http://www.ruby-forum.com/\.

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(c) }.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)

···

On 4/9/06, Logan Capaldo <logancapaldo@gmail.com> wrote:

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

> On 4/9/06, Brian Parkinson <parkI@whatevernot.com> wrote:
>>
>> Sven Klemm wrote:
>>
>> [deletia]
>>
>>> Module.const_get(s).new
>>
>> Thanks!
>>
>> I knew it would be a one-liner. :slight_smile:
>>
>> 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

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

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

Yup, very nice

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