Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to know when an instance variable gets set in Ruby

Tags:

ruby

Is there any way to override the setting of instance variables in Ruby?

Lets say I set an instance variable:

@foo = "bar"

Can I intercept that and do something (like record it or puts, for instance)

I suppose, I am trying to override the assignment operator for all types. Can this even be done?

The best I have come up with, so far, is this:

class Module
  def attr_log_accessor( *symbols )
    symbols.each { | symbol |
      module_eval( "def #{symbol}() @#{symbol}; end" )
      module_eval( "def #{symbol}=(val) 
                      @#{symbol} = val
                      puts \"#{symbol} has changed\"
                    end" )
    }
  end
end

Then, when I define the accessor and set it, my code gets executed:

class Test
  attr_log_accessor :foo

  def DoSomething
    self.foo = "bar"
  end
end

Unfortunately, this requires me to write self.foo = "bar", instead of @foo = "bar".

Any thoughts?

like image 788
Brian Genisio Avatar asked Apr 18 '10 02:04

Brian Genisio


2 Answers

No you can't do this directly. The best approach to this would be to only access the instance variables through getter/setter methods and override those.

like image 107
ryeguy Avatar answered Sep 28 '22 21:09

ryeguy


You could mess around with instance_variable_get, instance_variable_set and instance_variables. More can be found in this Ruby's Metaprogramming Toolbox article.

If you could describe why you're trying to do this we might be able to offer a better method.

like image 43
Robert Speicher Avatar answered Sep 28 '22 20:09

Robert Speicher