Dynamically create a hash of a objects variables values


#1

Tried my best to make this title as informative as possible but its
ended up a bit cryptic.

Say I have a class Record which represents records in a database and a
particular object has these instance variables

@a = 1
@b = 2
@c = 3

Id like to be able to create a hash that has the varible names i.e.
a,b,c as keys and then their values as the hash values.

e.g. {a=>1, b=>2, c=>3}

HOWEVER i would like this to be done dynamically so that if I add or
remove variables to my class definition the conversion method will
include these without me having to hard code them in the conversion
function.

Is this possible and if so what topic would this come under in a book?
Any tips or code snippets would be greatly appreciated.


#2

Alle Sunday 16 November 2008, Adam A. ha scritto:

Is this possible and if so what topic would this come under in a book?
Any tips or code snippets would be greatly appreciated.

The method instance_variables returns an array containing the names of
all the
instance variables of the receiver (including the leading @). The
instance_variable_get method, instead, returns the value of the instance
variable whose name is passed as argument. To do what you want, you can
do the
following:

res = {}
instance_variables.each{|v| res[v[1…-1]] = instance_variable_get(v)}
res

Here’s a full example:

class C
def initialize
@x = 1
@y = 2
@z = 3
end
def create_hash
res = {}
instance_variables.each{|v| res[v[1…-1]] =
instance_variable_get(v)}
res
end
end

p C.new.create_hash
=> {“x”=>1, “y”=>2, “z”=>3}

I hope this helps

Stefano


#3

Wow stefano thats perfect. Ill research that method more on the ruby
core website but what you wrote seems to be exactly what i wanted.

Thanks again.


#4

On 16.11.2008 10:46, Adam A. wrote:

Is this possible and if so what topic would this come under in a book?
Any tips or code snippets would be greatly appreciated.

Depends on what you want to do with the Hash but Struct may help you:

irb(main):001:0> S = Struct.new :a, :b, :c
=> S
irb(main):002:0> s = S.new 1,2,3
=> #
irb(main):003:0> s[:a]
=> 1
irb(main):004:0> s[:b]
=> 2
irb(main):005:0> s[:c]=100
=> 100
irb(main):006:0> s
=> #
irb(main):007:0>

If you want to add additional methods to the Struct you can do

S = Struct.new :a, :b, :c do
def some_method
(a + b) * c
end
end

Kind regards

robert