How can I do this without eval

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.

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.

On 9/2/06, J2M [email protected] 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 :wink:

finally http://www.rubycentral.com/book/ospace.html can be helpful.

Jan S. wrote:

model = const_get(model_name.to_s.capitalize)

Excellent, thank you.

On Sep 2, 2006, at 1:19 PM, Paul D. 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

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…