6

I have searched around, but can't find any built-in way to do convert an object (of my own creation) to a hash of values, so must needs look elsewhere.

My thought was to use .instance_variables, strip the @ from the front of each variable, and then use the attr_accessor for each to create the hash.

What do you guys think? Is that the 'Ruby Way', or is there a better way to do this?

2
  • If, perchance, you happen to be using Rails. .attributes will grab what you want. Commented Jul 9, 2010 at 3:10
  • You can also use 'hashable' gem stackoverflow.com/a/17889367/960702 Commented Jul 26, 2013 at 19:25

5 Answers 5

3

Assuming all data you want to be included in the hash is stored in instance variables:

class Foo
  attr_writer :a, :b, :c

  def to_hash
    Hash[*instance_variables.map { |v|
      [v.to_sym, instance_variable_get(v)]
    }.flatten]
  end
end

foo = Foo.new
foo.a = 1
foo.b = "Test"
foo.c = Time.now
foo.to_hash
 => {:b=>"Test", :a=>1, :c=>Fri Jul 09 14:51:47 0200 2010} 
Sign up to request clarification or add additional context in comments.

2 Comments

In the end I went with a simpler version of this (without the .map).
@Dukeh, could you please add your simpler version as another answer here?
2

Just this works

object.instance_values

Comments

1

I dont know of a native way to do this, but I think your idea of basically just iterating over all instance variables and building up a hash is basically the way to go. Its pretty straight-forward.

You can use Object.instance_variables to get an Array of all instance variables which you then loop over to get their values.

1 Comment

Agreed and if it is something you needed to do more than once, you could just extend Class with a to_hash method.
1

do you need a hash? or do you just need the convenience of using a hash?

if you need a has Geoff Lanotte's suggestion in Cody Caughlan's answer is nice. otherwise you could overload [] for your class. something like.

class Test
    def initialize v1, v2, v3
        @a = x
        @b = y
        @c = z
    end

    def [] x
        instance_variable_get("@" + x)
    end
end

n = Test.new(1, 2, 3)
p n[:b]

Comments

-1

Better use, <object>.attributes

it will returns a hash.

It is much more clean solution.

Cheers!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.