callmeback 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -17,7 +17,10 @@ Or add it to your gem file:
17
17
  gem 'callmeback'
18
18
 
19
19
  == Usage
20
+ Add +include Callmeback+ after **all** your module inclusions to be sure the gem works.
21
+
20
22
  class Example
23
+ include Mongoid::Document
21
24
  include Callmeback
22
25
 
23
26
  before :foo => :bar
@@ -36,6 +39,7 @@ Or add it to your gem file:
36
39
 
37
40
  Because this extension overrides the +.initialize+ method, if you need to redefine it, please add +callback_binding+ to your +.initialize+ method. Here is the same example as above but implemeting the +.initialize+ method:
38
41
  class Example
42
+ include Mongoid::Document
39
43
  include Callmeback
40
44
 
41
45
  after :foo => :bar
@@ -59,6 +63,8 @@ Because this extension overrides the +.initialize+ method, if you need to redefi
59
63
 
60
64
  You can use +before+, +after+ and +around+, as if you use the suggested method in the +ActiveSupport::Callbacks+ documentation.
61
65
 
66
+ Note that Mongoid is used in these examples but it *should* also work with ActiveRecord.
67
+
62
68
  == How is it work?
63
69
  First, this gem module defines the class methods +.before+, +.after+, +.around+ in your class. Then when you instanciate your class, the gem overrides your binded methods and wraps them to bind your custom callbacks.
64
70
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.1
1
+ 1.1.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "callmeback"
8
- s.version = "1.0.1"
8
+ s.version = "1.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Sebastien Azimi"]
12
- s.date = "2012-05-09"
12
+ s.date = "2013-01-15"
13
13
  s.description = ""
14
14
  s.email = "sebstp@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -35,7 +35,7 @@ Gem::Specification.new do |s|
35
35
  s.homepage = "http://github.com/suruja/callmeback"
36
36
  s.licenses = ["MIT"]
37
37
  s.require_paths = ["lib"]
38
- s.rubygems_version = "1.8.24"
38
+ s.rubygems_version = "1.8.23"
39
39
  s.summary = "Automatically provide dead-simple ActiveSupport callbacks to your instance methods."
40
40
 
41
41
  if s.respond_to? :specification_version then
@@ -1,50 +1,66 @@
1
+ require 'active_support/concern'
1
2
  require 'active_support/callbacks'
2
3
 
3
4
  module Callmeback
4
- extend ActiveSupport::Callbacks
5
+ extend ActiveSupport::Concern
6
+ include ActiveSupport::Callbacks
5
7
 
6
- def self.included(base)
7
- $callmeback_methods = {}
8
- base.extend(ClassMethods)
9
- base.module_eval do
10
- include ActiveSupport::Callbacks
11
- end
8
+ included do
9
+ # Initialize the callmeback methods and method index
10
+ self.callmeback_methods = {}
11
+ self.callmeback_method_index = 0
12
12
  end
13
13
 
14
- def initialize
15
- super
14
+ def initialize(*args, &block)
15
+ super(*args, &block)
16
+
17
+ # Overwrite the initialize method to perform the defined callbacks binding
16
18
  callback_binding
17
19
  end
18
20
 
19
21
  def callback_binding
20
- $callmeback_methods.each do |pst, vals|
21
- vals.each do |binded, callback|
22
- class_eval do
23
- define_method "wrapped_#{binded}" do
24
- prefix = 'callmeback'
25
- prefixed_binded = "#{prefix}_#{binded}"
22
+ self.class.callmeback_methods.each do |callback_prefix, callback_array|
23
+ callback_array.each do |callback_hash|
24
+ callback_hash.each do |binded, callbacks|
25
+ [callbacks].flatten.each do |callback|
26
+
27
+ binded_suffix = "method_#{self.class.callmeback_method_index}"
28
+ self.class.callmeback_method_index += 1
29
+
30
+ prefixed_wrapped_binded = "callmeback_wrapped_#{binded_suffix}"
31
+ prefixed_unwrapped_binded = "callmeback_unwrapped_#{binded_suffix}"
32
+
26
33
  class_eval do
27
- define_callbacks prefixed_binded
28
- set_callback prefixed_binded, pst, callback
29
- end
34
+ define_method prefixed_wrapped_binded do
35
+ class_eval do
36
+ define_callbacks prefixed_wrapped_binded
37
+ set_callback prefixed_wrapped_binded, callback_prefix, callback
38
+ end
39
+
40
+ run_callbacks prefixed_wrapped_binded do
41
+ send prefixed_unwrapped_binded
42
+ end
43
+ end
30
44
 
31
- run_callbacks prefixed_binded do
32
- send "unwrapped_#{binded}"
45
+ alias_method prefixed_unwrapped_binded, binded
46
+ alias_method binded, prefixed_wrapped_binded
33
47
  end
34
48
  end
35
-
36
- alias_method "unwrapped_#{binded}", binded
37
- alias_method binded, "wrapped_#{binded}"
38
49
  end
39
50
  end
40
51
  end
41
52
  end
42
53
 
43
54
  module ClassMethods
55
+ attr_accessor :callmeback_methods
56
+ attr_accessor :callmeback_method_index
57
+
44
58
  class_eval do
45
- [:before, :after, :around].each do |method_name|
46
- define_method method_name do |hsh|
47
- $callmeback_methods[method_name] = hsh
59
+ [:before, :after, :around].each do |callback_prefix|
60
+ define_method callback_prefix do |arg, &block|
61
+ self.callmeback_methods[callback_prefix] ||= []
62
+ arg = {:"#{arg}" => block} if block.is_a?(Proc)
63
+ self.callmeback_methods[callback_prefix] << arg
48
64
  end
49
65
  end
50
66
  end
@@ -5,14 +5,61 @@ class Example
5
5
  after :after_foo => :bar
6
6
  around :around_foo => :around_bar
7
7
 
8
+ before :multiple_before_foo => [:bar, :bar]
9
+ after :multiple_after_foo => [:bar, :bar]
10
+ around :multiple_around_foo => [:around_bar, :around_bar]
11
+
12
+ before :complex_foo => :bar
13
+ around :complex_foo => [:around_bar, :around_bar]
14
+ after :complex_foo => [:bar, :bar]
15
+
16
+ before :block_before_foo do
17
+ bar
18
+ end
19
+
20
+ after :block_after_foo do
21
+ bar
22
+ end
23
+
24
+ around :block_around_foo do |&block|
25
+ bar
26
+ block.call
27
+ bar
28
+ end
29
+
30
+ before :complex_with_blocks_foo do
31
+ bar
32
+ bar
33
+ end
34
+ after :complex_with_blocks_foo do
35
+ bar
36
+ end
37
+ around :complex_with_blocks_foo do |&block|
38
+ bar
39
+ block.call
40
+ bar
41
+ end
42
+
43
+ before :complex_with_methods_and_blocks_foo => [:bar, :bar]
44
+ after :complex_with_methods_and_blocks_foo do
45
+ bar
46
+ end
47
+ around :complex_with_methods_and_blocks_foo do |&block|
48
+ bar
49
+ block.call
50
+ bar
51
+ end
52
+
8
53
  def initialize
9
54
  @result = []
10
55
  callback_binding
11
56
  end
12
57
 
13
- def before_foo; foo; end
14
- def after_foo; foo; end
15
- def around_foo; foo; end
58
+ %w{before after around multiple_before multiple_after multiple_around complex block_before block_after block_around complex_with_blocks complex_with_methods_and_blocks}.each do |prefix|
59
+ define_method "#{prefix}_foo" do
60
+ foo
61
+ end
62
+ end
16
63
 
17
64
  private
18
65
  def foo
@@ -29,4 +29,56 @@ describe Callmeback do
29
29
  example.around_foo.should == %w{bar foo bar}
30
30
  end
31
31
  end
32
+
33
+ context "the callback value is an array of methods" do
34
+ describe ".before" do
35
+ it "should fire array-length callbacks before the original method is executed" do
36
+ example.multiple_before_foo.should == %w{bar bar foo}
37
+ end
38
+ end
39
+
40
+ describe ".after" do
41
+ it "should fire array-length callbacks after the original method is executed" do
42
+ example.multiple_after_foo.should == %w{foo bar bar}
43
+ end
44
+ end
45
+
46
+ describe ".around" do
47
+ it "should fire array-length callbacks around the original method is executed" do
48
+ example.multiple_around_foo.should == %w{bar bar foo bar bar}
49
+ end
50
+ end
51
+ end
52
+
53
+ context "the gem should handle complex callback structures" do
54
+ it "should fire the callbacks in the order of their call" do
55
+ example.complex_foo.should == %w{bar bar bar foo bar bar bar bar}
56
+ end
57
+ end
58
+
59
+ context "the gem should handle blocks as callbacks" do
60
+ it "should fire a callback block before the original method is executed" do
61
+ example.block_before_foo.should == %w{bar foo}
62
+ end
63
+
64
+ it "should fire a callback block after the original method is executed" do
65
+ example.block_after_foo.should == %w{foo bar}
66
+ end
67
+
68
+ it "should fire a callback block around the original method is executed" do
69
+ example.block_around_foo.should == %w{bar foo bar}
70
+ end
71
+ end
72
+
73
+ context "the gem should handle blocks as callbacks" do
74
+ it "should fire the callbacks in the order of their call" do
75
+ example.complex_with_blocks_foo.should == %w{bar bar bar foo bar bar}
76
+ end
77
+ end
78
+
79
+ context "the gem should handle blocks as callbacks and methods" do
80
+ it "should fire the callbacks in the order of their call" do
81
+ example.complex_with_methods_and_blocks_foo.should == %w{bar bar bar foo bar bar}
82
+ end
83
+ end
32
84
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: callmeback
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-09 00:00:00.000000000 Z
12
+ date: 2013-01-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -192,7 +192,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
192
192
  version: '0'
193
193
  segments:
194
194
  - 0
195
- hash: -762099405
195
+ hash: 2462921630949056169
196
196
  required_rubygems_version: !ruby/object:Gem::Requirement
197
197
  none: false
198
198
  requirements:
@@ -201,7 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
201
201
  version: '0'
202
202
  requirements: []
203
203
  rubyforge_project:
204
- rubygems_version: 1.8.24
204
+ rubygems_version: 1.8.23
205
205
  signing_key:
206
206
  specification_version: 3
207
207
  summary: Automatically provide dead-simple ActiveSupport callbacks to your instance