13

I have a Ruby class. I want to get an instance variable from an argument to a method in that class. I can do get all of the instance variables as an array:

self.instance_variables

However, I want to get the instance variable named arg, specifically:

class MyClass
  def get_instance_variable(arg)
    hash_of_instance_variables[arg]
  end
end

object.get_instance_variable('my_instance_var')

How do I compute hash_of_instance_variables?

2
  • Can you elaborate? Your question is not very clear. Commented May 13, 2010 at 21:28
  • 4
    It looks like you're hoping to build a hash that maps instance variables to their values so that you can retrieve the value of the instance variable. If so, why? Use instance_variable_get. Commented Feb 2, 2011 at 3:17

5 Answers 5

25

To create a hash of all instance variables you can use the following code:

class Object
  def instance_variables_hash
    Hash[instance_variables.map { |name| [name, instance_variable_get(name)] } ]
  end
end

But as cam mentioned in his comment, you should use instance_variable_get method instead:

object.instance_variable_get :@my_instance_var
Sign up to request clarification or add additional context in comments.

Comments

13

Question is quite old but found rails solution for this: instance_values

This is first answer in google so maybe it will help someone.

3 Comments

Thanks for helping the community. I no longer use ruby/rails, moved on to node.js. Bests
The code used by Rails is almost identical to the accepted answer with the exception that Rails strips the leading @.
instance_values worked for me and was simpler. Thanks! (now tested with Rails 6)
1
class MyClass    
def variables_to_hash
      h = {}
      instance_variables.each{|a|
        s = a.to_s
        n = s[1..s.size]
        v = instance_variable_get a
        h[n] = v
      }
      h
    end
end

1 Comment

Note that s[1..s.size] can be replaced with s[1..-1].
0

For Ruby 2.6+, you can pass a block to the to_h method, leading to very DRY syntax:

# Some instance variables
instance_variable_set(:@a, 'dog')
#=> "dog"
instance_variable_set(:@b, 'cat')
#=> "cat"

# Array of instance variable names
instance_variables
#=> [:@a, :@b]

# Hash of instance variable names and values, including leading @
instance_variables.to_h { |k| [k, instance_variable_get(k)] }
#=> { :@a => "dog", :@b => "cat" }

# Hash of instance variable names and values, excluding leading @
instance_variables.to_h { |k| [k[1..-1].to_sym, instance_variable_get(k)] }
#=> { :a => "dog", :b => "cat" }

Comments

-1

Ruby on Rails has a couple of built-in ways to do this that you might find meet your needs.

user = User.new(first: 'brian', last: 'case')

user.attributes

{"first"=>"brian", "last"=>"case"}

user.serializeable_hash

{"first"=>"brian", "last"=>"case"}

1 Comment

This only applies to Rails models (instances of ActiveRecord::Base). For an arbitrary Ruby object, @sufleR's answer works.

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.