Skip to content

Instantly share code, notes, and snippets.

@mdouchement
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mdouchement/895289eb96d7f1e87be3 to your computer and use it in GitHub Desktop.
Save mdouchement/895289eb96d7f1e87be3 to your computer and use it in GitHub Desktop.
Ruby before filter
module MethodInterception
def before_filter(*meths, &blk)
return @wrap_next_method = true if meths.empty?
meths.delete_if { |meth| wrap(meth, &blk) if method_defined?(meth) }
@intercepted_methods += meths
end
private
def wrap(meth, &blk)
old_meth = instance_method(meth)
define_method(meth) do |*args, &block|
# before filter execution
blk.call(*args) if blk
# original method call
old_meth.bind(self).call(*args, &block)
end
end
def method_added(meth)
return super unless @intercepted_methods.include?(meth) || @wrap_next_method
return super if @recursing == meth
@recursing = meth # protect against infinite recursion
wrap(meth)
@recursing = nil
@wrap_next_method = false
super
end
def self.extended(klass)
klass.instance_variable_set(:@intercepted_methods, [])
klass.instance_variable_set(:@recursing, false)
klass.instance_variable_set(:@wrap_next_method, false)
end
end
class HelloWord
extend MethodInterception
before_filter(:say_hello) do |*args|
puts "Before the message '#{args[0]}'"
end
def say(message)
puts message
end
end
# HelloWord.new.say('hello:')
# => Before the message 'hello!'
# => hello!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment