tags:

views:

369

answers:

2

Regardless of whether it's good practice or not, how can I dynamically call accessor methods in Ruby?

Here's an example class:

class Test_Class
  attr_accessor :a, :b
end

I can use the Object.send method to read the variable...

instance.a = "value"
puts( instance.send( "a" ) )
# => value

But I'm having a hard time trying to write to it. These throw "wrong number of arguments (1 for 0) (ArgumentError)"

instance.send("a", "value")

and

instance.method("a").call("value")

Please help me StackOverflow!

+11  A: 

I am not a ruby expert, but I think that you could do:

instance.send("a=", "value")
Angela
Works, great! I guess the equal sign is part of the method name?
Joe Zack
Yes, the equals sign in the conventional way to define setter methods in Ruby.I would use a symbol rather than a string though. `instance.send(:a=, "value")`
robw
Yep. attr_accessor makes two methods:def v; @v; endand def v=(value); @v=value; end
Angela
+2  A: 

You can also directly access instance variables of an object using instance_variable_* functions:

instance = Test_Class.new                 # => #<Test_Class:0x12b3b84>

# instance variables are lazily created after first use of setter,
# so for now instance variables list is empty:
instance.instance_variables                # => []

instance.instance_variable_set(:@a, 123)   # => 123
instance.a                                 # => 123
instance.instance_variables                # => ["@a"]
instance.instance_variable_get("@a")       # => 123
Marcin Urbanski