# How can I do this without eval

**URL:** <https://www.ruby-forum.com/t/how-can-i-do-this-without-eval/67305>\
**Category:** Ruby\
**Created:** [September 2, 2006, 1:19am UTC](https://www.ruby-forum.com/t/how-can-i-do-this-without-eval/67305 "2006-09-02T01:19:49Z")\
**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:** [September 2, 2006, 1:19am UTC](https://www.ruby-forum.com/t/how-can-i-do-this-without-eval/67305/1 "2006-09-02T01:19:49Z")

</div>

def load\_default\_attributes(model\_name, options = {})  
fixture = options[:fixture] || :default  
attributes = temp\_attributes = model = {}  
instance\_eval \<\<-FIN  
temp\_attributes = #{model\_name.to\_s.pluralize}("#{fixture}")  
model = #{model\_name.to\_s.capitalize}  
FIN  
.  
.  
.  
end

I know there must be a neater way to get hold of a class (or in this  
case a Rails model) and with the temp\_attributes to get hold of a  
fixture, can anybody shed some metaprogramming light?

Thanks.

---

<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:** [September 2, 2006, 1:29am UTC](https://www.ruby-forum.com/t/how-can-i-do-this-without-eval/67305/2 "2006-09-02T01:29:56Z")

</div>

James Mccarthy wrote:

> def load\_default\_attributes(model\_name, options = {})  
> fixture = options[:fixture] || :default  
> attributes = temp\_attributes = model = {}  
> instance\_eval \<\<-FIN  
> temp\_attributes = #{model\_name.to\_s.pluralize}("#{fixture}")

send model\_name.to\_s.pluralize, fixture

> ```
> model = #{model_name.to_s.capitalize}
> 
> ```

self.class.const\_get model\_name.to\_s.capitalize

> ```
> FIN
> .
> .
> .
> 
> ```
> 
> end
> 
> I know there must be a neater way to get hold of a class (or in this  
> case a Rails model) and with the temp\_attributes to get hold of a  
> fixture, can anybody shed some metaprogramming light?

The above should work in principle; however, take a  
look at ri Object#send and Module#const\_get in case  
you run into any problems.

(Disclaimer: respondent is not proficient with Rails.)

> Thanks.

---

<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:** [September 2, 2006, 1:47am UTC](https://www.ruby-forum.com/t/how-can-i-do-this-without-eval/67305/3 "2006-09-02T01:47:51Z")

</div>

On 9/2/06, J2M [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> def load\_default\_attributes(model\_name, options = {})  
> fixture = options[:fixture] || :default  
> attributes = temp\_attributes = model = {}  
> instance\_eval \<\<-FIN  
> temp\_attributes = #{model\_name.to\_s.pluralize}(“#{fixture}”)  
> model = #{model\_name.to\_s.capitalize}  
> FIN

Hi,

model = const\_get(model\_name.to\_s.capitalize)

Classes are constants. So you can get them by name (string or symbol)  
with Module#const\_get

temp\_attributes… I don’t know what fixtures are, I’ll just say that  
you can

- call a method with Object#send(name, arg1, arg2) or send(name, \*args)
- get/set instance variable with  
instance\_variable\_get/instance\_variable\_set (don’t forget the @!  
my\_object.instance\_variable\_get(‘@name’) )
- class variables with Module#class\_variable\_get/…\_set

and generally, look into Module, Class, Object and Kernel for other  
useful methods 😉

finally [http://www.rubycentral.com/book/ospace.html](http://www.rubycentral.com/book/ospace.html) can be helpful.

---

<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:** [September 2, 2006, 3:35am UTC](https://www.ruby-forum.com/t/how-can-i-do-this-without-eval/67305/4 "2006-09-02T03:35:56Z")

</div>

Jan S. wrote:

> model = const\_get(model\_name.to\_s.capitalize)

Excellent, thank you.

---

<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:** [September 2, 2006, 10:53pm UTC](https://www.ruby-forum.com/t/how-can-i-do-this-without-eval/67305/5 "2006-09-02T22:53:10Z")

</div>

On Sep 2, 2006, at 1:19 PM, Paul D. wrote:

> - J2M (removed\_email\_address@domain.invalid) wrote:
> 
> > Jan S. wrote:
> > 
> > > model = const\_get(model\_name.to\_s.capitalize)
> 
> This might be more appropriate:
> 
> model\_class = const\_get(model\_name.to\_s.classify)

Also if you are already within rails you may as well use #constantize

model\_class = model\_name.to\_s.classify.constantize

-Ezra

---

<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:** [September 2, 2006, 10:19pm UTC](https://www.ruby-forum.com/t/how-can-i-do-this-without-eval/67305/6 "2006-09-02T22:19:06Z")

</div>

- J2M (removed\_email\_address@domain.invalid) wrote:

> Jan S. wrote:
> 
> > model = const\_get(model\_name.to\_s.capitalize)

This might be more appropriate:

model\_class = const\_get(model\_name.to\_s.classify)

Classify will take care of things that capitalize misses, like  
underscores and extraneous plurals. Take a look at the following  
output:

# test strings and test methods

strings = %w{blog\_post layers magazine\_subscribers}  
methods = %w{capitalize classify}.map { |m| m.intern }

# iterate over test strings and handle each one

puts strings.map { |str|  
“’#{str}’\n” \<\< methods.map { |meth|  
" #{meth}:\t’#{str.send(meth)}’"  
}.join("\n")  
}

Produces the following:

‘blog\_post’  
capitalize: ‘Blog\_post’  
classify: ‘BlogPost’  
‘layers’  
capitalize: ‘Layers’  
classify: ‘Layer’  
‘magazine\_subscribers’  
capitalize: ‘Magazine\_subscribers’  
classify: ‘MagazineSubscriber’

Hope that helps…
