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.

--
Posted via http://www.ruby-forum.com/.

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.

···

On 9/2/06, J2M <james2mccarthy@gmail.com> 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

Jan Svitok wrote:

model = const_get(model_name.to_s.capitalize)

Excellent, thank you.

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...

···

* J2M (james2mccarthy@gmail.com) wrote:

Jan Svitok wrote:

> model = const_get(model_name.to_s.capitalize)

--
Paul Duncan <pabs@pablotron.org> pabs in #ruby-lang (OPN IRC)
http://www.pablotron.org/ OpenPGP Key ID: 0x82C29562

Jan Svitok 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

···

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

* J2M (james2mccarthy@gmail.com) wrote:

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...

--
Paul Duncan <pabs@pablotron.org> pabs in #ruby-lang (OPN IRC)
http://www.pablotron.org/ OpenPGP Key ID: 0x82C29562