ruby-callbacks 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/ruby-callbacks.rb +194 -0
- metadata +46 -0
@@ -0,0 +1,194 @@
|
|
1
|
+
# module Callbackable allows to add callbacks
|
2
|
+
# before and after methods
|
3
|
+
#
|
4
|
+
# == Example
|
5
|
+
#
|
6
|
+
# require "ruby-callbacks"
|
7
|
+
#
|
8
|
+
# class Cat
|
9
|
+
# include Callbacks
|
10
|
+
#
|
11
|
+
# attr_accessor :name, :colour
|
12
|
+
#
|
13
|
+
# callback :after, :eat, :play
|
14
|
+
# callback :before, :eat, :sleep
|
15
|
+
#
|
16
|
+
# def initialize(name, colour)
|
17
|
+
# @name = name
|
18
|
+
# @colour = colour
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# def sleep
|
22
|
+
# puts "#{@name} the cat is sleeping"
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# def eat
|
26
|
+
# puts "#{@name} the cat is eating"
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# def play
|
30
|
+
# puts "#{@name} the cat is playing"
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# kitty = Cat.new("Kitty", "black")
|
36
|
+
#
|
37
|
+
# kitty.eat
|
38
|
+
# # => Kitty the cat is sleeping
|
39
|
+
# # => Kitty the cat is eating
|
40
|
+
# # => Kitty the cat is playing
|
41
|
+
|
42
|
+
module Callbacks
|
43
|
+
|
44
|
+
class UnknownEventException < Exception; end
|
45
|
+
|
46
|
+
# md5 for word "method"
|
47
|
+
SALT = "ea9f6aca279138c58f705c8d4cb4b8ce"
|
48
|
+
|
49
|
+
def self.included(base)
|
50
|
+
|
51
|
+
base.class_eval do
|
52
|
+
@@_method_chain = Hash.new
|
53
|
+
@@_callbacks_running = Array.new
|
54
|
+
# show current_method_chain
|
55
|
+
def self.method_chain
|
56
|
+
@@_method_chain
|
57
|
+
end
|
58
|
+
|
59
|
+
# allows to add a callback to already initialized class
|
60
|
+
# == Example
|
61
|
+
# class Cat
|
62
|
+
# include Callbacks
|
63
|
+
#
|
64
|
+
# def purr
|
65
|
+
# # purr
|
66
|
+
# end
|
67
|
+
#
|
68
|
+
# def sleep
|
69
|
+
# # sleep
|
70
|
+
# end
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# Cat.add_callback(:after, :purr, :sleep)
|
74
|
+
# Cat.new.purr # purr, then sleep
|
75
|
+
def self.add_callback(event, method, callback)
|
76
|
+
if callbacks_exist? method
|
77
|
+
callback(event, method, callback)
|
78
|
+
else
|
79
|
+
callback(event, method, callback)
|
80
|
+
run_callback(method)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Delete existing callback
|
85
|
+
# if callback == nil deletes all callbacks on given *method*
|
86
|
+
# == Example
|
87
|
+
# class Cat
|
88
|
+
# include Callbacks
|
89
|
+
# callback :after, :purr, :sleep
|
90
|
+
# def purr
|
91
|
+
# # purr
|
92
|
+
# end
|
93
|
+
#
|
94
|
+
# def sleep
|
95
|
+
# # sleep
|
96
|
+
# end
|
97
|
+
# end
|
98
|
+
#
|
99
|
+
# Cat.callbacks_exist?(:purr) # => true
|
100
|
+
# Cat.del_callback(:purr)
|
101
|
+
# Cat.callbacks_exist?(:purr) # => false
|
102
|
+
def self.del_callback(method, callback = nil)
|
103
|
+
if callback
|
104
|
+
@@_method_chain[method].delete_if{|c| c == callback }
|
105
|
+
del_all_callbacks(method) if @@_method_chain[method].size == 1
|
106
|
+
else
|
107
|
+
del_all_callbacks(method)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# Are callback *callback* on this method already exists?
|
112
|
+
def self.callback_exists?(method, callback)
|
113
|
+
!@@_method_chain[method.to_sym].detect{|c| c == callback.to_sym }.nil?
|
114
|
+
end
|
115
|
+
|
116
|
+
# Are callbacks on this method already exists?
|
117
|
+
def self.callbacks_exist?(method)
|
118
|
+
!@@_method_chain[method.to_sym].nil?
|
119
|
+
end
|
120
|
+
|
121
|
+
class << self
|
122
|
+
def new_method_name(method)
|
123
|
+
"#{method}_#{SALT}"
|
124
|
+
end
|
125
|
+
|
126
|
+
def method_added(method)
|
127
|
+
if callbacks_exist?(method) && !@@_callbacks_running.include?(method)
|
128
|
+
run_callback(method)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
# Register new callback
|
134
|
+
# See main example
|
135
|
+
def callback(event, method, callback)
|
136
|
+
reg_callback(event.to_sym, method.to_sym, callback.to_sym)
|
137
|
+
end
|
138
|
+
|
139
|
+
def del_all_callbacks(method)
|
140
|
+
undef_method method
|
141
|
+
alias_method method, new_method_name(method)
|
142
|
+
@@_callbacks_running.delete_if {|m| m == method}
|
143
|
+
@@_method_chain[method] = nil
|
144
|
+
end
|
145
|
+
|
146
|
+
def run_callback(method)
|
147
|
+
return if @@_callbacks_running.include? method
|
148
|
+
alias_method new_method_name(method), method
|
149
|
+
undef_method method
|
150
|
+
|
151
|
+
@@_callbacks_running.push method
|
152
|
+
|
153
|
+
define_method method do
|
154
|
+
call_method_chain(method)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def reg_callback(event, method, callback)
|
159
|
+
raise UnknownEventException if (event != :before && event != :after)
|
160
|
+
@@_method_chain[method] = [new_method_name(method)] unless @@_method_chain[method]
|
161
|
+
|
162
|
+
if event === :before
|
163
|
+
reg_before_callback(method, callback)
|
164
|
+
elsif event === :after
|
165
|
+
reg_after_callback(method, callback)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def reg_before_callback(method, callback)
|
170
|
+
@@_method_chain[method].insert \
|
171
|
+
(@@_method_chain[method].index new_method_name(method)), callback
|
172
|
+
end
|
173
|
+
|
174
|
+
def reg_after_callback(method, callback)
|
175
|
+
@@_method_chain[method].push callback
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
def call_method_chain(method)
|
181
|
+
result = nil
|
182
|
+
@@_method_chain[method].each do |action|
|
183
|
+
if action == self.class.new_method_name(method)
|
184
|
+
result = self.send(action)
|
185
|
+
else
|
186
|
+
self.send(action)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
return result
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
metadata
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-callbacks
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ilya Boltnev
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-30 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: module Callbackable allows to add callbacks before and after methods
|
15
|
+
email:
|
16
|
+
- ilya@boltnev.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/ruby-callbacks.rb
|
22
|
+
homepage: https://github.com/boltnev/ruby-callbacks
|
23
|
+
licenses: []
|
24
|
+
post_install_message:
|
25
|
+
rdoc_options: []
|
26
|
+
require_paths:
|
27
|
+
- lib
|
28
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
requirements: []
|
41
|
+
rubyforge_project:
|
42
|
+
rubygems_version: 1.8.25
|
43
|
+
signing_key:
|
44
|
+
specification_version: 3
|
45
|
+
summary: This is a gem for providing callbacks
|
46
|
+
test_files: []
|