From: Brian Takita Date: 2008-09-30T07:17:34+09:00 Subject: Way to intercept method calls? - Reopened Hello, I read the thread. http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/676 Matz mentioned that he does not think its "worthy" which I interpret to mean there is either no use case or the use case is not beneficial to satisfy. If there was a way to intercept all incoming calls, it would make the "blank slate" pattern obsolete. FTWDK, The "blank slate" pattern implementation means, one would remove all methods from an object so method_missing can be used. It is used to implement a lightweight and transparent Proxy to another object. ActiveRecord Association proxies make heavy use of the blank slate pattern. Here is an example implementation: class Foo instance_methods.each {|m| undef_method(m) unless m =~ /__/} def initialize(proxy_target) @proxy_target = proxy_target end def method_missing(name, *args, &block) @proxy_target.__send__(name, *args, &block) end end The problem with this pattern is that it is imperative. If another library defines a method on Object after Foo is loaded, then the blank slate for Foo breaks. For example: require "foo" class Object def bar "I don't want to be called" end end class ProxyTarget def bar "I want to be called" end end foo = Foo.new("the proxy target") foo.bar # "I don't want to be called" So to solve this particular problem, you can apply the blank slate on object instantiation: class Foo def initialize(proxy_target) @proxy_target = proxy_target class << self instance_methods.each {|m| undef_method(m) unless(m =~ /^_/ || m.to_s == 'object_id')} end def method_missing(name, *args, &block) @proxy_target.__send__(name, *args, &block) end end end For some reason, #method_missing also needs to be redefined on #initialize. Ideally, Ruby would support a way to intercept method invocation before its sent to the real implementation. I believe Python allows this by redefining one of the __ methods (I don't know which one, but I think I saw somebody do this) on the proxy class. Something like the following would be nice: class Foo def initialize(proxy_target) @proxy_target = proxy_target end def __call__(name, *args, &block) if m =~ /^_/ || m.to_s == 'object_id' super else @proxy_target.__send__(name, *args, &block) end end end Anyways, removing the need for the "blank slate" pattern is a concrete use case for this feature. I do believe that method invocation interception would open the door for some powerful abstraction and really cool libraries. Also, are feature requests for Ruby officially on rubyforge.org tracker? Thanks, Brian