Skip to content

Instantly share code, notes, and snippets.

@sbishep
Created February 27, 2015 17:31
Show Gist options
  • Save sbishep/09509566cee1f5bb4115 to your computer and use it in GitHub Desktop.
Save sbishep/09509566cee1f5bb4115 to your computer and use it in GitHub Desktop.
Callbacks in pure ruby
module CallbackPureRuby
def self.included(klass)
klass.extend ClassMethods
klass.initialize_included_features
end
module ClassMethods
def initialize_included_features
@callbacks = Hash[:before, {}, :after, {}]
class << self
attr_accessor :callbacks
attr_accessor :setting_callback
end
end
def store_callbacks(type, method_name, *callback_methods)
callbacks[type][method_name] = callback_methods
if !setting_callback
prepend_method(method_name)
end
end
def method_missing(method, *args, &block)
if method.to_s =~ /^before|after$/
store_callbacks(method, *args)
else
super
end
end
def prepend_method(original_method)
@setting_callback = true
save_with_callbacks = Module.new do
define_method(original_method) do |*args, &block|
trigger_callbacks(original_method, :before)
return_val = super()
trigger_callbacks(original_method, :after)
return_val
end
end
prepend save_with_callbacks
@setting_callback = false
end
end
def trigger_callbacks(method_name, callback_type)
unless self.class.callbacks[callback_type][method_name].nil?
self.class.callbacks[callback_type][method_name].each{ |callback| __send__ callback }
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment