nakajima-booty-call 0.0.1 → 0.0.2
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/booty-call.rb +1 -0
- data/lib/booty_call/callbacker.rb +12 -2
- data/lib/booty_call/hook.rb +2 -2
- data/lib/booty_call/introspector.rb +24 -16
- data/lib/booty_call/observed_method.rb +31 -0
- data/lib/booty_call.rb +2 -1
- metadata +5 -3
data/lib/booty-call.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/booty_call.rb'
|
@@ -19,7 +19,6 @@ module BootyCall
|
|
19
19
|
|
20
20
|
def extend_klass
|
21
21
|
klass.class_eval do
|
22
|
-
meta_eval { attr_reader :pristine_cache, :callback_cache }
|
23
22
|
@pristine_cache = Hash.new
|
24
23
|
@callback_cache = { :after => Hash.new([]), :before => Hash.new([]) }
|
25
24
|
extend ClassMethods
|
@@ -42,6 +41,9 @@ module BootyCall
|
|
42
41
|
end
|
43
42
|
|
44
43
|
def redefine_method(method_id)
|
44
|
+
safe_method_id = method_id.to_s
|
45
|
+
safe_method_id.gsub!(/=/, '__EQUALS__')
|
46
|
+
safe_method_id.gsub!(/\?/, '__PREDICATE__')
|
45
47
|
klass.class_eval(<<-EOS, "(__DELEGATION__)", 1)
|
46
48
|
def #{method_id}(*args, &block)
|
47
49
|
catch(#{method_id.to_sym.inspect}) do
|
@@ -52,13 +54,21 @@ module BootyCall
|
|
52
54
|
end
|
53
55
|
end
|
54
56
|
|
55
|
-
def #{
|
57
|
+
def #{safe_method_id}_without_callbacks(*args, &block)
|
56
58
|
__PRISTINE__(#{method_id.inspect}, *args, &block)
|
57
59
|
end
|
58
60
|
EOS
|
59
61
|
end
|
60
62
|
|
61
63
|
module ClassMethods
|
64
|
+
def pristine_cache
|
65
|
+
@pristine_cache || superclass.pristine_cache
|
66
|
+
end
|
67
|
+
|
68
|
+
def callback_cache
|
69
|
+
@callback_cache || superclass.callback_cache
|
70
|
+
end
|
71
|
+
|
62
72
|
def run_callbacks_for(target, position, method_id, *results)
|
63
73
|
callbacks = callback_cache[position][method_id.to_sym]
|
64
74
|
|
data/lib/booty_call/hook.rb
CHANGED
@@ -17,8 +17,8 @@ module BootyCall
|
|
17
17
|
callback(:after, method_id, *args, &block)
|
18
18
|
end
|
19
19
|
|
20
|
-
def observe(method_id, &block)
|
21
|
-
@introspector.observe(method_id, &block)
|
20
|
+
def observe(method_id, options={}, &block)
|
21
|
+
@introspector.observe(method_id, options, &block)
|
22
22
|
end
|
23
23
|
|
24
24
|
def callback(position, method_id, *args, &block)
|
@@ -1,18 +1,19 @@
|
|
1
1
|
module BootyCall
|
2
2
|
class Introspector
|
3
|
-
attr_reader :klass
|
3
|
+
attr_reader :klass, :options
|
4
4
|
|
5
|
-
def initialize(klass)
|
6
|
-
@klass = klass
|
5
|
+
def initialize(klass, options={})
|
6
|
+
@klass, @options = klass, options
|
7
7
|
@observed_methods = { }
|
8
8
|
end
|
9
9
|
|
10
10
|
def observe_klass!
|
11
11
|
@observed ||= begin
|
12
12
|
this = self
|
13
|
-
|
13
|
+
hook = options[:metaclass] ? :singleton_method_added : :method_added
|
14
|
+
klass.meta_def(hook) do |m|
|
14
15
|
this.check_method(m)
|
15
|
-
end
|
16
|
+
end; true
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
@@ -20,22 +21,29 @@ module BootyCall
|
|
20
21
|
not not @observed_methods[method_id]
|
21
22
|
end
|
22
23
|
|
23
|
-
def observe(method_id, &block)
|
24
|
+
def observe(method_id, options={}, &block)
|
24
25
|
observe_klass!
|
25
|
-
@observed_methods[method_id] ||=
|
26
|
-
@observed_methods[method_id].
|
27
|
-
set.push(block) if block_given?
|
28
|
-
set.tap.compact!.uniq!
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def check_method(method_id)
|
33
|
-
handlers = @observed_methods.delete(method_id)
|
34
|
-
handlers.each(&:call) rescue nil
|
26
|
+
@observed_methods[method_id] ||= ObservedMethod.new(method_id, options)
|
27
|
+
@observed_methods[method_id].push(block) if block_given?
|
35
28
|
end
|
36
29
|
|
37
30
|
def defined_methods
|
38
31
|
(klass.instance_methods - Object.instance_methods).map(&:to_sym)
|
39
32
|
end
|
33
|
+
|
34
|
+
def check_method(sym)
|
35
|
+
@observed_methods.each do |method_id, observer|
|
36
|
+
stop_observing(method_id) do
|
37
|
+
observer.match(sym)
|
38
|
+
observer.valid?
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def stop_observing(method_id, &block)
|
44
|
+
@observed_methods.delete(method_id).tap do |observer|
|
45
|
+
@observed_methods[method_id] = observer if block.try(:call, observer)
|
46
|
+
end
|
47
|
+
end
|
40
48
|
end
|
41
49
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module BootyCall
|
2
|
+
class ObservedMethod
|
3
|
+
attr_reader :method_id
|
4
|
+
|
5
|
+
def initialize(method_id, options={})
|
6
|
+
@method_id = method_id
|
7
|
+
@callbacks = []
|
8
|
+
@count = 0
|
9
|
+
@times = options[:times] || 1
|
10
|
+
end
|
11
|
+
|
12
|
+
def match(sym)
|
13
|
+
return unless case method_id
|
14
|
+
when Symbol then valid?
|
15
|
+
when Regexp then valid? and method_id.try(:match, sym.to_s)
|
16
|
+
else ; nil
|
17
|
+
end
|
18
|
+
@callbacks.each { |fn| fn.call(sym) }
|
19
|
+
@count += 1
|
20
|
+
end
|
21
|
+
|
22
|
+
def valid?
|
23
|
+
@times.eql?(:infinite) or @count < @times
|
24
|
+
end
|
25
|
+
|
26
|
+
def push(*args)
|
27
|
+
@callbacks += args
|
28
|
+
@callbacks.tap.compact!.uniq!
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/booty_call.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
$LOAD_PATH << File.dirname(__FILE__) + '/booty_call'
|
2
2
|
|
3
3
|
module BootyCall
|
4
|
-
VERSION = '0.0.
|
4
|
+
VERSION = '0.0.2'
|
5
5
|
end
|
6
6
|
|
7
7
|
require 'rubygems'
|
8
8
|
require 'nakajima'
|
9
9
|
require 'callbacker'
|
10
|
+
require 'observed_method'
|
10
11
|
require 'introspector'
|
11
12
|
require 'hook'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nakajima-booty-call
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pat Nakajima
|
@@ -31,10 +31,12 @@ extra_rdoc_files: []
|
|
31
31
|
|
32
32
|
files:
|
33
33
|
- lib/booty_call
|
34
|
-
- lib/
|
34
|
+
- lib/booty-call.rb
|
35
|
+
- lib/booty_call.rb
|
35
36
|
- lib/booty_call/hook.rb
|
37
|
+
- lib/booty_call/callbacker.rb
|
36
38
|
- lib/booty_call/introspector.rb
|
37
|
-
- lib/booty_call.rb
|
39
|
+
- lib/booty_call/observed_method.rb
|
38
40
|
has_rdoc: false
|
39
41
|
homepage: http://github.com/nakajima/booty-call
|
40
42
|
post_install_message:
|