0

I have a class Sample

Sample.class returns

(id :integer, name :String, date :date)

and A hash has all the given attributes as its keys. Then how can I initialize a variable of Sample without assigning each attribute independently.

Something like

Sample x = Sample.new

x.(attr) = Hash[attr]

How can I iterate through the attributes, the problem is Hash contains keys which are not part of the class attributes too

Dave Newton
  • 158,873
  • 26
  • 254
  • 302

3 Answers3

1

Take a look at this article on Object initialization. You want an initialize method.

EDIT You might also take a look at this SO post on setting instance variables, which I think is exactly what you're trying to do.

Community
  • 1
  • 1
sczizzo
  • 3,196
  • 20
  • 28
  • I want to iterate through the attributes for the inizialization. Is there any way to do that? – user1449980 Jun 13 '12 at 01:29
  • Sure, you might save their names to a class variable (i.e. an array like `@@attrs = [:id, :name, :date]`) and loop over them later. – sczizzo Jun 13 '12 at 01:35
1
class Sample
  attr_accessor :id, :name, :date
end

h = {:id => 1, :name => 'foo', :date => 'today', :extra1 => '', :extra2 => ''}

init_hash = h.select{|k,v| Sample.method_defined? "#{k}=" }

# This will work
s = Sample.new
init_hash.each{|k,v| s.send("#{k}=", v)}

# This may work if constructor takes a hash of attributes
s = Sample.new(init_hash)
Abe Voelker
  • 30,124
  • 14
  • 81
  • 98
0

Try this:

class A
  attr_accessor :x, :y, :z
end

a = A.new
my_hash = {:x => 1, :y => 2, :z => 3, :nono => 5}

If you do not have the list of attributes that can be assigned from the hash, you can do this:

my_attributes = (a.methods & my_hash.keys)

Use a.instance_variable_set(:@x = 1) syntax to assign values:

my_attributes.each do |attr|
  a.instance_variable_set("@#{attr.to_s}".to_sym, my_hash[attr])
end

Note(Thanks to Abe): This assumes that either all attributes to be updated have getters and setters, or that any attribute which has getter only, does not have a key in my_hash.

Good luck!

Anil
  • 3,899
  • 1
  • 20
  • 28
  • Might want to test that with an `attr_reader :nono` in the class definition ;) – Abe Voelker Jun 13 '12 at 16:12
  • @AbeVoelker `my_attributes = (a.methods & my_hash.keys)` does it. – Anil Jun 13 '12 at 18:50
  • `attr_reader :nono` will create a `nono` (reader) method, but not a `nono=` (writer) method. `my_attributes = (a.methods & my_hash.keys)` is only checking for reader methods. Should attributes be assigned that don't have writer methods? – Abe Voelker Jun 13 '12 at 19:04
  • @AbeVoelker Good point. I guess Dave Newton will have to select based on his needs. I am editing my response to reflect this consideration. – Anil Jun 13 '12 at 21:50