Created
June 11, 2012 23:33
-
-
Save anklos/2913422 to your computer and use it in GitHub Desktop.
simple callbacks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Callbacks | |
def self.included(base) | |
base.class_eval do | |
extend ClassMethods | |
include InstanceMethods | |
end | |
end | |
module ClassMethods | |
def define_callback(callback_name) | |
callbacks[callback_name] = [] | |
callback_hook = | |
Proc.new do |*callback_action_and_options| | |
action = callback_action_and_options[0] | |
unless action.is_a?(Symbol) or action.respond_to?(:call) | |
raise "unrecognized callback action: #{action.inspect}" | |
end | |
opts = callback_action_and_options[1] | |
unless !opts or opts.keys.all? { |key| [:if, :unless].include?(key) } | |
raise "unrecognized callback keys in: #{opts.inspect}" | |
end | |
callbacks[callback_name] << [action, opts] | |
end | |
singleton = class << self; self end | |
singleton.send(:define_method, callback_name, callback_hook) | |
end | |
def proxy_callback(nominal_name, effective_names) | |
proxy_hook = | |
Proc.new do |*callback_action_and_options| | |
effective_names.each do |effective_name| | |
send(effective_name, *callback_action_and_options) | |
end | |
end | |
singleton = class << self; self end | |
singleton.send(:define_method, nominal_name, proxy_hook) | |
end | |
def callbacks | |
@callbacks ||= {} | |
end | |
end | |
module InstanceMethods | |
def invoke_callback(callback_name) | |
self.class.callbacks[callback_name].all? do |callback_action, options| | |
(options and !should_run?(options)) or | |
(case callback_action | |
when Symbol | |
self.send(callback_action) | |
when Proc | |
callback_action.call(self) | |
end != false) | |
end | |
end | |
private | |
def should_run?(options) | |
if options[:if] | |
send(options[:if]) | |
elsif options[:unless] | |
!send(options[:unless]) | |
else | |
true | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Task | |
define_callback :after_failure | |
define_callback :after_success | |
def failed(name, message) | |
invoke_callback :after_failure, [name, message] | |
end | |
def success(name, message) | |
invoke_callback :after_success, [name, message] | |
end | |
end | |
module Notify | |
def self.included(base) | |
base.class_eval do | |
extend ClassMethods | |
include InstanceMethods | |
end | |
end | |
module ClassMethods | |
after_failure :send_notification | |
def notify(email, after=5) | |
@@email = email | |
@@after = after | |
end | |
def send_notification | |
# send mail | |
end | |
end | |
end | |
module Record | |
def self.included(base) | |
base.class_eval do | |
extend ClassMethods | |
include InstanceMethods | |
end | |
end | |
module ClassMethods | |
after_success :record_success | |
after_failure :record_failure | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment