Creating arbitrary objects

I've probably overlooked something, and hopefully someone can help me out. I want to be able to create arbitrary object from the contents of a string.

For example, if I had the following string:

classname = "Array"

How can I create an Array object, knowing only that the variable classname held the name of some class as a string.

You're looking for Object.const_get():

irb(main):003:0> class_obj = Object.const_get("Array")
=> Array
irb(main):004:0> arr = class_obj.new
=>

Hope that helps.

James Edward Gray II

···

On Apr 29, 2005, at 12:38 PM, Matthew Thill wrote:

I've probably overlooked something, and hopefully someone can help me out. I want to be able to create arbitrary object from the contents of a string.

For example, if I had the following string:

classname = "Array"

How can I create an Array object, knowing only that the variable classname held the name of some class as a string.

this is from my utility lib:

   harp:~ > cat a.rb
   def klass_stamp(hierachy, *a, &b)
     ancestors = hierachy.split(%r/::/)
     parent = Object
     while((child = ancestors.shift))
       klass = parent.const_get child
       parent = klass
     end
     klass::new(*a, &b)
   end

   module A
     module B
       module C
         class X
           class Y
             class Z
               def initialize(*bits, &block)
                 n = 0
                 bits.reverse.each_with_index{|bit, i| n |= (bit << i)}
                 block.call n
               end
             end
           end
         end
       end
     end
   end

   klass_stamp('A::b::C::x::Y::Z', 1, 0, 1, 0, 1, 0){ |n| p n }

   harp:~ > ruby a.rb
   42

HTH.

-a

···

On Sat, 30 Apr 2005, Matthew Thill wrote:

I've probably overlooked something, and hopefully someone can help me
out. I want to be able to create arbitrary object from the contents of a
string.

For example, if I had the following string:

classname = "Array"

How can I create an Array object, knowing only that the variable
classname held the name of some class as a string.

--

email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
renunciation is not getting rid of the things of this world, but accepting
that they pass away. --aitken roshi

===============================================================================

Matthew Thill wrote:

I've probably overlooked something, and hopefully someone can help me out. I want to be able to create arbitrary object from the contents of a string.

For example, if I had the following string:

classname = "Array"

How can I create an Array object, knowing only that the variable classname held the name of some class as a string.

Thanks for the responses everyone. I have plenty of new ideas to work with now.

Yes, that is exactly what I wanted. Thank you.

James Edward Gray II wrote:

···

On Apr 29, 2005, at 12:38 PM, Matthew Thill wrote:

I've probably overlooked something, and hopefully someone can help me out. I want to be able to create arbitrary object from the contents of a string.

For example, if I had the following string:

classname = "Array"

How can I create an Array object, knowing only that the variable classname held the name of some class as a string.

You're looking for Object.const_get():

irb(main):003:0> class_obj = Object.const_get("Array")
=> Array
irb(main):004:0> arr = class_obj.new
=>

Hope that helps.

James Edward Gray II

Don't you mean Module.const_get()?

···

On 4/29/05, James Edward Gray II <james@grayproductions.net> wrote:

On Apr 29, 2005, at 12:38 PM, Matthew Thill wrote:

> I've probably overlooked something, and hopefully someone can help me
> out. I want to be able to create arbitrary object from the contents of
> a string.
>
> For example, if I had the following string:
>
> classname = "Array"
>
> How can I create an Array object, knowing only that the variable
> classname held the name of some class as a string.

You're looking for Object.const_get():

If your class is nested in a module or other class, you might want to do
something like:

irb:0> module A
irb:1> class B
irb:2> class C
irb:3> end
irb:2> end
irb:1> end
=> nil
irb:0> classname = 'A::b::C'
=> "A::b::C"
irb:0> klass = classname.split('::').inject(Class) do |sum, elem|
irb:1* sum.const_get(elem)
irb:1> end
=> A::b::C
irb:0> klass.new
=> #<A::b::C:0xb7d12640>

···

On Sat, 2005-04-30 at 03:05 +0900, James Edward Gray II wrote:

On Apr 29, 2005, at 12:38 PM, Matthew Thill wrote:

> I've probably overlooked something, and hopefully someone can help me
> out. I want to be able to create arbitrary object from the contents of
> a string.
>
> For example, if I had the following string:
>
> classname = "Array"
>
> How can I create an Array object, knowing only that the variable
> classname held the name of some class as a string.

You're looking for Object.const_get():

irb(main):003:0> class_obj = Object.const_get("Array")
=> Array
irb(main):004:0> arr = class_obj.new
=>

Hope that helps.

James Edward Gray II

Yes, my bad. Module.const_get() called on Object, is what I meant.

James Edward Gray II

···

On Apr 29, 2005, at 1:24 PM, Joe Van Dyk wrote:

Don't you mean Module.const_get()?

actually, Module#const_get, or Object.const_get, IMHO :slight_smile:

Also, the OP might look at #allocate. #allocate never needs arguments,
#new might fail without arguments. Of course, allocate doesn't
initialize...

klass = "Array"
Object.const_get(klass).allocate #==>

cheers,
Mark

···

On 4/29/05, James Edward Gray II <james@grayproductions.net> wrote:

On Apr 29, 2005, at 1:24 PM, Joe Van Dyk wrote:

> Don't you mean Module.const_get()?

Yes, my bad. Module.const_get() called on Object, is what I meant.

Whoah, how did this escape me for so long!?

#allocate

Awesome, this'll let me abuse classes in a whole new fashion
*cue evil laughter echoing from the depths of a dark forest*

Thanks a million for the insight,
Ilmari

···

On 29.4.2005, at 22:50, Mark Hubbart wrote:

Also, the OP might look at #allocate. #allocate never needs arguments,
#new might fail without arguments. Of course, allocate doesn't
initialize...

klass = "Array"
Object.const_get(klass).allocate #==>

cheers,
Mark