# Is there a better way

**URL:** <https://www.ruby-forum.com/t/is-there-a-better-way/63087>\
**Category:** Ruby\
**Created:** [June 11, 2006, 10:03pm UTC](https://www.ruby-forum.com/t/is-there-a-better-way/63087 "2006-06-11T22:03:26Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![noagenda](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/8c91f0/32.png) [@noagenda](https://www.ruby-forum.com/u/noagenda)\
**Post date:** [June 11, 2006, 10:03pm UTC](https://www.ruby-forum.com/t/is-there-a-better-way/63087/1 "2006-06-11T22:03:26Z")

</div>

Is there an neater way to achieve this without using that clunky eval  
and inline substitution?

def test\_confirmation(object, test\_attribute, test\_values = {},  
attributes = {})  
instance = eval("#{object}.new(attributes)")  
test\_values.each do |value|  
instance.send("#{test\_attribute}=", value)  
instance.send("#{test\_attribute}\_confirmation=", value)  
assert !instance.save  
assert instance.errors.invalid?(test\_attribute)  
end  
end

Just feels a little clunky and wanted some pointers to improve my ruby.  
Any thoughts would be useful.

---

<div class="post-metadata">

**Author:** ![noagenda](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/8c91f0/32.png) [@noagenda](https://www.ruby-forum.com/u/noagenda)\
**Post date:** [June 11, 2006, 10:27pm UTC](https://www.ruby-forum.com/t/is-there-a-better-way/63087/2 "2006-06-11T22:27:55Z")

</div>

On Jun 11, 2006, at 3:03 PM, James McCarthy wrote:

> ```
> instance = eval("#{object}.new(attributes)")
> 
> ```

instance = Object.const\_get(object).new(attributes)

Hope that helps.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![noagenda](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/8c91f0/32.png) [@noagenda](https://www.ruby-forum.com/u/noagenda)\
**Post date:** [June 11, 2006, 10:28pm UTC](https://www.ruby-forum.com/t/is-there-a-better-way/63087/3 "2006-06-11T22:28:07Z")

</div>

On Jun 11, 2006, at 4:03 PM, James McCarthy wrote:

> ```
> assert instance.errors.invalid?(test_attribute)
> end
> 
> ```
> 
> end
> 
> Just feels a little clunky and wanted some pointers to improve my  
> ruby.  
> Any thoughts would be useful.

You can pass classes as arguments to functions:  
test\_confirmation(SomeClass, …)

instance = object.new(attributes)

If the problem is you have to get a string, use const\_get  
e.g.  
Object.const\_get(object).new(attributes)

The only problem with this is that it doesn’t work for nested  
constants (e.g. Net::HTTP). So to generalize that you do

instance = object.split(/::/).inject(Object) { |base, child|  
base.const\_get(child) }.new(attributes)

the #send s seem fine to me, much better than just straight eval’ing  
the stuff.

---

<div class="post-metadata">

**Author:** ![noagenda](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/8c91f0/32.png) [@noagenda](https://www.ruby-forum.com/u/noagenda)\
**Post date:** [June 11, 2006, 10:35pm UTC](https://www.ruby-forum.com/t/is-there-a-better-way/63087/4 "2006-06-11T22:35:02Z")

</div>

Joel VanderWerf wrote:

> ```
> object.send(:new, attributes)
> 
> ```

Duh. Of course, as Logan said, you can just object.new(attributes). And  
unlike me he was not lazy and wrote out the inject solution.

---

<div class="post-metadata">

**Author:** ![noagenda](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/8c91f0/32.png) [@noagenda](https://www.ruby-forum.com/u/noagenda)\
**Post date:** [June 11, 2006, 10:31pm UTC](https://www.ruby-forum.com/t/is-there-a-better-way/63087/5 "2006-06-11T22:31:23Z")

</div>

James McCarthy wrote:

> Is there an neater way to achieve this without using that clunky eval  
> and inline substitution?
> 
> def test\_confirmation(object, test\_attribute, test\_values = {},  
> attributes = {})  
> instance = eval("#{object}.new(attributes)")

If object is supposed to be a class:

```
             object.send(:new, attributes)

```

If object is a string that names a class you will have to use const\_get  
to avoid eval. Check the archives for a good way to do that using  
inject.

> ```
> test_values.each do |value|
> instance.send("#{test_attribute}=", value)
> instance.send("#{test_attribute}_confirmation=", value)
> 
> ```

AFAIK there is no better way to call setter methods, if the name of the  
method is a parameter. If you only need to set the instance vars, you  
can use #instance\_variable\_set, but that’s not the same thing as calling  
the accessor method.

HTH.

---

<div class="post-metadata">

**Author:** ![noagenda](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/8c91f0/32.png) [@noagenda](https://www.ruby-forum.com/u/noagenda)\
**Post date:** [June 11, 2006, 10:35pm UTC](https://www.ruby-forum.com/t/is-there-a-better-way/63087/6 "2006-06-11T22:35:13Z")

</div>

On Mon, Jun 12, 2006 at 05:03:43AM +0900, James McCarthy wrote:  
} Is there an neater way to achieve this without using that clunky eval  
} and inline substitution?  
}  
} def test\_confirmation(object, test\_attribute, test\_values = {},  
} attributes = {})  
} instance = eval(“#{object}.new(attributes)”)  
} test\_values.each do |value|  
} instance.send(“#{test\_attribute}=”, value)  
} instance.send(“#{test\_attribute}\_confirmation=”, value)  
} assert !instance.save  
} assert instance.errors.invalid?(test\_attribute)  
} end  
} end  
}  
} Just feels a little clunky and wanted some pointers to improve my  
ruby.  
} Any thoughts would be useful.

Take a look at  
[http://redcorundum.blogspot.com/2006/05/kernelqualifiedconstget.html](http://redcorundum.blogspot.com/2006/05/kernelqualifiedconstget.html)

–Greg
