-1

I need to get the superset of instance variables available across all objects of a class, i.e. [@a,@b,@c] below:

class Test
  attr_accessor :a,:b,:c
end

obj = Test.new
obj.a = 10

obj2 = Test.new
obj2.b = 20

obj.instance_variables  # => [@a]
obj2.instance_variable  # => [@b]

The need over here is to get a list containing [@a,@b,@c]. An alternative is to look for obj.class.instance_methods. However, it will also return other instance methods present in class.

How this can be achieved?

sawa
  • 165,429
  • 45
  • 277
  • 381
Rakesh
  • 15
  • 2
  • [May be of help](http://stackoverflow.com/questions/6365638/how-to-get-class-instances-in-ruby) – potashin Mar 10 '16 at 09:46
  • Not clear what you mean. "**The need is to get the superset of instance variable available across all objects of class**," so if an object had `@d`, (on which an accessor is not defined), you want `@d` to be included. Is that right? – sawa Mar 10 '16 at 10:16
  • What "**superset**"? Do you mean "union"? – sawa Mar 10 '16 at 10:19
  • Your result cannot be reproduced. – sawa Mar 10 '16 at 10:23
  • 1
    Your question suggests intent to misuse metaprogramming. What are you trying to achieve with this? – Mladen Jablanović Mar 10 '16 at 10:25
  • I am not an owner of class, and i need to write a generator where action on value of instance_variable is dependent on name of instance variable. – Rakesh Mar 10 '16 at 11:29

2 Answers2

1

You might be looking for

obj.class.instance_methods(false)

which returns all methods that have been defined by your class and are not inherited.

bogl
  • 1,864
  • 1
  • 15
  • 32
  • No it will provide me with other instance methods as well present in class Test defined using "def" – Rakesh Mar 10 '16 at 11:27
  • What is the difference between the variables or methods you want to see, and those you do not want to see? – bogl Mar 10 '16 at 12:24
0

You can predefine the instance variables to get them into instance_variables list. Like this

class Test
  attr_accessor :a, :b, :c

  def initialize
    @a, @b, @c = nil
  end
end

obj = Test.new
obj.instance_variables
# => [:@a, :@b, :@c]

I try this rly OP way to get instance variables. I rly dont know if this works in your case. (You need to define module before other classes)

class Module
  alias_method :attr_accessor2, :attr_accessor

  def attr_accessor(symbol, *smth)
    # ([symbol] + smth).map{|sym| puts sym}
    attr_accessor2(symbol, *smth)

    define_method("all_instance_variables") do
      (([symbol] + smth).map{|s| "@#{s}".to_sym} + self.instance_variables).uniq!
    end
  end
end

class Test
  attr_accessor :a, :b, :c
end

obj = Test.new
obj.all_instance_variables
# => [:@a, :@b, :@c]
Lukas Baliak
  • 2,849
  • 2
  • 23
  • 26
  • I am not the owner of Test class and Test class definition is split across lot many files. Only option for me is to monkey patch. I can monkey patch the Test class with initialize method only if i am aware of list of all instance variables, that is what i need – Rakesh Mar 10 '16 at 11:26
  • @Rakesh maybe this OP way, but i rly dont know if this will help you or will work in your case. – Lukas Baliak Mar 10 '16 at 12:25
  • Overloading attr_accessor is a way out. However I am not sure whether instance_variable definition like class Test; @e ; end will be handled. However i believe this can be handled if I make a unique list obtained from obj.all_instance_variables & obj.instance_variables. – Rakesh Mar 11 '16 at 09:29