2

I am coming from Java, and want to know if I can 'set' an instance variable for an object using introspection.

For example, if I have the following class declaration, with the two instance variables, first_attribute and second_attribute:

class SomeClass  
  attr_accessor :first_attribute
  attr_reader :second_attribute

  def initialize()  
    # ...
  end
end

I want to be able to get the instance methods, presumably by calling SomeClass.instance_methods and know which of those instance methods are read/write vs. just read-only.

In Java I can do this by:

PropertyDescriptor[] properties = PropertyUtils.GetPropertyDescriptors(SomeClass);
for (prop : properties) {
  if (prop.getWriteMethod() != null) {
    //  I can set this one!
  }
}

How do I do this in Ruby?

Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338
Tucker
  • 81
  • 6

1 Answers1

4

There's not really anything built-in like the Java property stuff, but you can do it pretty easily like this:

self.class.instance_methods.grep(/\w=$/)

Which will return the names of all the setter methods on the class.

Austin Taylor
  • 5,437
  • 1
  • 23
  • 29
  • 1
    `attr_reader :x` adds `x` method, which is a getter. `attr_writer :x` adds `x=` method, which is the setter. `attr_accessor :x` does both. In short, by using those "macros", you add methods to the class by which you manipulate the field. So Austin Taylor is correct; filter the instance methods only to those who end in a single "=" and you get your setter methods. If you have 5 extra mins, take a look at this short article: http://www.rubyist.net/~slagell/ruby/accessors.html – dimitarvp May 11 '11 at 15:45
  • Note that in Ruby, while defining new class one actually executes code in `Class` context so the use of `self.class.instance_methods` vs `self.instance_methods` depends on the context where this is written. When the former is **inside** a method definition and the latter **outside** method definition, they produce the same result. – Laas May 11 '11 at 18:45