Skip to content

Instantly share code, notes, and snippets.

@roman
Created February 3, 2010 19:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save roman/293953 to your computer and use it in GitHub Desktop.
Save roman/293953 to your computer and use it in GitHub Desktop.
module MethodInterceptor
def self.included(base)
base.extend(ClassMethods)
base.send(:include, InstanceMethods)
base.class_eval do
# we declare the method_list on the class env
@_instance_method_list = base.instance_methods.inject(Hash.new) do |methods, method_name|
# we undef all methods
if !%w(__send__ __id__ method_missing class).include?(method_name)
methods[method_name.to_sym] = base.instance_method(method_name)
base.send(:undef_method, method_name)
end
methods
end
end
end
module ClassMethods
def _instance_method_list
@_instance_method_list
end
def method_added(name)
return if [:before_method, :method_missing].include?(name)
_instance_method_list[name] = self.instance_method(name)
self.send(:undef_method, name)
nil
end
end
module InstanceMethods
def before_method(method_name, *args)
# by defaults it always will be called
true
end
def method_missing(name, *args)
if self.class._instance_method_list.key?(name)
if before_method(name, *args)
self.class._instance_method_list[name].bind(self).call(*args)
else
super
end
else
super
end
end
end
end
class Say
include MethodInterceptor
def before_method(method_name, *args)
# you cannot say hello world!
return !(method_name == :say && args[0] == 'hello world')
end
def say(msg)
puts msg
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment