# Simple Q: object creation to be determined by incoming data

**URL:** <https://www.ruby-forum.com/t/simple-q-object-creation-to-be-determined-by-incoming-data/104675>\
**Category:** Ruby\
**Created:** [May 21, 2007, 1:38pm UTC](https://www.ruby-forum.com/t/simple-q-object-creation-to-be-determined-by-incoming-data/104675 "2007-05-21T13:38:46Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![toadkicker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/5fc32e/32.png) [@toadkicker](https://www.ruby-forum.com/u/toadkicker)\
**Post date:** [May 21, 2007, 1:38pm UTC](https://www.ruby-forum.com/t/simple-q-object-creation-to-be-determined-by-incoming-data/104675/1 "2007-05-21T13:38:46Z")

</div>

I’m almost embarrassed to ask this, because I’m bound to be pointed to  
some  
code that I’ve almost certainly read already, but here goes my ruby  
newbie  
question:

I have an incoming stream of data in separated chunks, each having a  
beginning word that defines that chunk’s place in the world (how it will  
respond to #to\_s, etc). Currently, I model each chunk as an object;  
each  
has its own class. Basically, I’m unserializing object data, but I  
provide  
the object functionality. I want to do off-the-stream object creation,  
and  
so I’ve went and done something like:

instance\_eval( “#{class\_name\_from\_stream\_chunk}.new(  
data\_from\_stream\_chunk  
)” )

Is this the only way to do this (by “way”, I mean the code and also the  
manner), and if not, the best way?

---

<div class="post-metadata">

**Author:** ![toadkicker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/5fc32e/32.png) [@toadkicker](https://www.ruby-forum.com/u/toadkicker)\
**Post date:** [May 21, 2007, 2:02pm UTC](https://www.ruby-forum.com/t/simple-q-object-creation-to-be-determined-by-incoming-data/104675/2 "2007-05-21T14:02:48Z")

</div>

On Mon, May 21, 2007 at 08:38:02PM +0900, Todd B. wrote:

> I want to do off-the-stream object creation, and  
> so I’ve went and done something like:
> 
> instance\_eval( “#{class\_name\_from\_stream\_chunk}.new( data\_from\_stream\_chunk  
> )” )
> 
> Is this the only way to do this (by “way”, I mean the code and also the  
> manner), and if not, the best way?

If the class names are all top-level, e.g. “Foo”, then

obj = Object.const\_get(classname).new(\*args)

If the class names are all under one module, e.g. the string “Foo”  
really  
means Bar::Foo, then

obj = Bar.const\_get(classname).new(\*args)

(I’d recommend this form, as it prevents your stream creating objects  
except  
those directly under a ‘safe’ module)

If the class names are arbitary nested modules, e.g. they could be  
“Bar::Foo”, then

obj = classname.split(’::’).inject(Object) { |k,c| k.const\_get©  
}.new(\*args)

This assumes that your data\_from\_stream\_chunk has been split into an  
array  
called ‘args’ (the ‘shellwords’ modules is useful for this). And also  
you  
have to make everything the correct type, e.g. if your object expects  
an integer constructor then you’ll have to call to\_i.

HTH,

Brian.

---

<div class="post-metadata">

**Author:** ![toadkicker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/5fc32e/32.png) [@toadkicker](https://www.ruby-forum.com/u/toadkicker)\
**Post date:** [May 21, 2007, 2:40pm UTC](https://www.ruby-forum.com/t/simple-q-object-creation-to-be-determined-by-incoming-data/104675/3 "2007-05-21T14:40:53Z")

</div>

Thanks guys, const\_get is what I was looking for!

---

<div class="post-metadata">

**Author:** ![toadkicker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/5fc32e/32.png) [@toadkicker](https://www.ruby-forum.com/u/toadkicker)\
**Post date:** [May 21, 2007, 2:03pm UTC](https://www.ruby-forum.com/t/simple-q-object-creation-to-be-determined-by-incoming-data/104675/4 "2007-05-21T14:03:48Z")

</div>

Alle lunedì 21 maggio 2007, Todd B. ha scritto:

> instance\_eval( “#{class\_name\_from\_stream\_chunk}.new( data\_from\_stream\_chunk  
> )” )
> 
> Is this the only way to do this (by “way”, I mean the code and also the  
> manner), and if not, the best way?

I’m not sure I understand correctly your question. I think you don’t  
need to  
use instance eval. If class\_name\_from\_stream\_chunk is a string/symbol  
and the  
class is defined in the module M (if it is defined top level, substitute  
M  
with Kernel), you can do:

M.const\_get(class\_name\_from\_stream\_chunk).new(data\_from\_stream\_chunk)

You can also define a method which wraps this in a simpler interface:

def M.new\_from\_chunk name, data  
const\_get(name).new(data)  
end

and use it this way:

res = M.new(class\_name\_from\_stream\_chunk, data\_from\_stream\_chunk)

I hope this helps

Stefano
