views:

44

answers:

1

I have a class like so:

class Item
  attr_accessor :item_id, :name, :address, :description, :facilities, :ratings, :directions, :geo, :images, :video, :availability

  def self.create options={}
    item = Item.new
    item.item_id = options[:item_id]
    item.name = options[:name]
    item.description = options[:desc]
    item.ratings = options[:rating]
    return item
  end

end

How can I make the 'create' method in such a way as to read the given options that are getting passed and try to create them without having to specify their name explicitly?

ie. no item.name = options[:item_id] etc etc.... just... computer brain thinks "ah... i see the option 'option[:name], let me try to create an attribute with that same name and this value!..."

+1  A: 
class Item
  attr_accessor :a, :b, :c
  def initialize(options = {})
    options.each {
      |k,v|
      self.send( "#{k.to_s}=".intern, v)
    }
  end
end

i = Item.new(:a => 1, :c => "dog" )
puts i.a
# outputs: 1
puts i.c
# outputs: "dog"

If you are feeling particularly adventurous:

class Object
  def metaclass; class << self; self; end; end
end

class Item
  def initialize(options = {})
    options.each {
      |k,v|
      self.metaclass.send(:attr_accessor, k)
      self.send( "#{k.to_s}=".intern, v)
    }
  end
end

i = Item.new(:a => 1, :c => "dog")
puts i.a
# 1
puts i.c
# dog

i2 = Item.new
puts i2.a
# ERROR
Sam Saffron
you're my new best friend!
holden