callmeback 1.0.1 → 1.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.
@@ -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