Spying on Instance Variables in Ruby

A little while back, a few colleagues and I were spiking a proxy concept based on extending an existing web server. We wanted to check out an instance variable (eg, @very_secret) in a framework object which did not have an accessor. In the past, we'd used send (eg, secretive_object.send :hello_private) to get at privates, but send is only for methods. We were just digging around doing some debugging, so we opened the relevant class and added a public accessor for the instance variable to see what was happening. However, we thought there must be a more elegant way to do access instance variables outside the class, and one has just come to mind (at last!):

secretive_object.instance_eval { @very_secret }

instance_eval lets us run the code block in the context of secretive_object. Ie, self == secretive_object, so we can get at all the hidden stuff.

It's a rather different approach to other languages like C# and Java where accessing private variables and private methods are part of a reflection/introspection API.



2 responses to “Spying on Instance Variables in Ruby”

5 08 2009
Jonathan Weiss (19:12:49) :

Ever heard of instance_variable_get and instance_variable_set?


secretive_object.instance_variable_set("@very_secret", 'foo')

6 08 2009
Michael Schubert (04:47:49) :

What Jonathan said. Every time you think you need to use class_eval, instance_eval or eval. Think again.