# Instantiate different class based on variable contents

**URL:** <https://www.ruby-forum.com/t/instantiate-different-class-based-on-variable-contents/165083>\
**Category:** Ruby\
**Created:** [April 8, 2009, 10:40pm UTC](https://www.ruby-forum.com/t/instantiate-different-class-based-on-variable-contents/165083 "2009-04-08T22:40:42Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![stephen\_OSD](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/df788c/32.png) [@stephen\_OSD](https://www.ruby-forum.com/u/stephen_OSD)\
**Post date:** [April 8, 2009, 10:40pm UTC](https://www.ruby-forum.com/t/instantiate-different-class-based-on-variable-contents/165083/1 "2009-04-08T22:40:42Z")

</div>

Lets say I have a two classes, Foo and Bar.

In some code, I have a variable that can either contain the test ‘Foo’  
or the text ‘Bar’. If it contains Foo, I would like to call Foo.new  
(v1, v2), if it contains Bar, I would like to call Bar.new(v1, v2).

Obviously I could create an IF statement, such as

if var == ‘Foo’ then  
Foo.new(…)  
elsif var == ‘Bar’ then  
Bar.new(…)  
end if

Or if I want to get fancy, maybe a dispatch table:

dispatch = {  
‘Foo’ =\> Foo,  
‘Bar’ =\> Bar  
}

obj = dispatch[var].new(…)

Is there another Ruby way to do this sort of thing?

Thanks,

Stephen.

---

<div class="post-metadata">

**Author:** ![stephen\_OSD](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/df788c/32.png) [@stephen\_OSD](https://www.ruby-forum.com/u/stephen_OSD)\
**Post date:** [April 8, 2009, 11:01pm UTC](https://www.ruby-forum.com/t/instantiate-different-class-based-on-variable-contents/165083/2 "2009-04-08T23:01:48Z")

</div>

On Wed, Apr 8, 2009 at 2:40 PM, stephen O’D  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)wrote:

> dispatch = {  
> ‘Foo’ =\> Foo,  
> ‘Bar’ =\> Bar  
> }
> 
> obj = dispatch[var].new(…)
> 
> Is there another Ruby way to do this sort of thing?

Object.const\_get(var).new(…)

or with ActiveSupport:

var.constantize.new(…)

---

<div class="post-metadata">

**Author:** ![stephen\_OSD](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/df788c/32.png) [@stephen\_OSD](https://www.ruby-forum.com/u/stephen_OSD)\
**Post date:** [April 8, 2009, 11:14pm UTC](https://www.ruby-forum.com/t/instantiate-different-class-based-on-variable-contents/165083/3 "2009-04-08T23:14:07Z")

</div>

On Apr 8, 2009, at 4:40 PM, stephen O’D wrote:

> dispatch = {  
> ‘Foo’ =\> Foo,  
> ‘Bar’ =\> Bar  
> }
> 
> obj = dispatch[var].new(…)

This can sometimes be the best approach because if you simply  
translate arbitrary text to a class name you are allowing arbitrary  
classes to be instantiated. It just depends on where your text is  
coming from.

Rick DeNatale recently posted in [ruby-talk:332670] this nice solution  
to mapping text to class objects:

---

<div class="post-metadata">

**Author:** ![stephen\_OSD](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/df788c/32.png) [@stephen\_OSD](https://www.ruby-forum.com/u/stephen_OSD)\
**Post date:** [April 9, 2009, 12:01am UTC](https://www.ruby-forum.com/t/instantiate-different-class-based-on-variable-contents/165083/4 "2009-04-09T00:01:03Z")

</div>

On Apr 8, 10:01 pm, Tony A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> [medioh.com](http://medioh.com)  
> Thanks, works perfectly!

---

<div class="post-metadata">

**Author:** ![stephen\_OSD](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/df788c/32.png) [@stephen\_OSD](https://www.ruby-forum.com/u/stephen_OSD)\
**Post date:** [April 9, 2009, 12:05am UTC](https://www.ruby-forum.com/t/instantiate-different-class-based-on-variable-contents/165083/5 "2009-04-09T00:05:44Z")

</div>

On Apr 8, 10:13 pm, Gary W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> translate arbitrary text to a class name you are allowing arbitrary
> 
> > ```
> > inject(Object) { |scope, name| scope.const_defined?(name) ?
> > 
> > ```
> > 
> > scope.const\_get(name) : scope.const\_missing(name) }  
> > end

Thanks for the tip - I _think_ my data is well enough sanitized, but  
you just never know so I may well use this approach. Knowing how to  
do things with Object.const\_get is useful even if I don’t use it.
