big_spoon 0.1.0 → 0.2.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/README.md +48 -50
- data/VERSION +1 -1
- data/big_spoon.gemspec +2 -2
- data/lib/big_spoon/hook.rb +1 -1
- data/lib/big_spoon.rb +5 -1
- data/spec/lib/big_spoon_spec.rb +44 -1
- metadata +3 -3
data/README.md
CHANGED
@@ -1,41 +1,18 @@
|
|
1
1
|
# Big Spoon
|
2
|
-
|
3
|
-
It adds before and after callbacks to ANY method in any Ruby class.
|
4
|
-
Basically, now you can add hooks and/or callback to **any** Ruby method without fear of reprisals.
|
2
|
+
**Big Spoon** adds ActiveRecord::Base-style `before_*` and `after_*` callbacks around ANY Ruby method.
|
5
3
|
|
6
|
-
|
4
|
+
It's like a sandwich, where your method is the meat and your callbacks are the bread.
|
7
5
|
|
8
6
|
## Basic Usage
|
9
7
|
|
10
|
-
|
11
|
-
|
8
|
+
Out-of-the box, **Big Spoon** adds callbacks that are similar to ActiveRecord::Base. Of course there's, like, at least three ways to do that. So **Big
|
9
|
+
Spoon** supports all of 'em. Whatever form you choose, it'll swaddle your methods in the warm of `before` and `after` hooks.
|
12
10
|
|
13
|
-
|
14
|
-
class User
|
15
|
-
hooks do
|
16
|
-
before :get_your_hands_off_of_my_woman, :listen_to_the_darkness
|
17
|
-
after :get_your_hands_off_of_my_woman { listen_to_moar_darkness! }
|
18
|
-
end
|
11
|
+
### ActiveRecord::Base-style
|
19
12
|
|
20
|
-
|
21
|
-
puts "Get your hands off of my woman, motherf*cker!"
|
22
|
-
end
|
13
|
+
The most straightforward way is to do it ActiveRecord::Base style, which is to define a callback in the top of your class like so:
|
23
14
|
|
24
|
-
protected
|
25
|
-
def listen_to_the_darkness!
|
26
|
-
`osascript "tell iTunes to play some awesome"`
|
27
|
-
end
|
28
|
-
|
29
|
-
def listen_to_moar_darkness
|
30
|
-
`osascript "tell iTuens to continue not to suck after that last rad song"`
|
31
|
-
end
|
32
|
-
end
|
33
15
|
```
|
34
|
-
|
35
|
-
This is designed not to conflict with Rails callbacks and their siblings. **But if'n
|
36
|
-
you're a real scofflaw (_and you f*cking should be!_), you can just do it normal-like:**
|
37
|
-
|
38
|
-
```ruby
|
39
16
|
class User
|
40
17
|
before_believe_in_a_thing_called_love :listen_to_the_rhythm_of_my_heart
|
41
18
|
|
@@ -46,12 +23,43 @@ class User
|
|
46
23
|
def listen_to_the_rhythm_of_my_heart
|
47
24
|
listen("127.0.0.1") do
|
48
25
|
match /(lub|dub)/ do
|
49
|
-
puts "Edgar Allan
|
26
|
+
puts "Edgar Allan Poe!"
|
50
27
|
end
|
51
28
|
end
|
52
29
|
end
|
53
30
|
````
|
54
31
|
|
32
|
+
### DataMapper-style
|
33
|
+
|
34
|
+
DataMapper has what I consider a slightly better API for doing this, specifically:
|
35
|
+
|
36
|
+
```
|
37
|
+
class User
|
38
|
+
after :save, :get_your_hands_off_of_my_woman
|
39
|
+
end
|
40
|
+
```
|
41
|
+
|
42
|
+
So **Big Spoon** supports that notation, too! This is in order to avoid conflicts with Rails callbacks and their siblings. But if'n you're a real scofflaw, you can just do it normal-like.
|
43
|
+
|
44
|
+
|
45
|
+
### Block-style
|
46
|
+
|
47
|
+
If you're STILL interested in avoiding any potential conflicts, you can isolate your hooks
|
48
|
+
completely by wrapping them in a block:
|
49
|
+
|
50
|
+
```
|
51
|
+
class User
|
52
|
+
hooks do
|
53
|
+
before :get_your_hands_off_of_my_woman, :listen_to_the_darkness
|
54
|
+
end
|
55
|
+
|
56
|
+
protected
|
57
|
+
def listen_to_the_darkness!
|
58
|
+
`osascript "tell iTunes to play some awesome"`
|
59
|
+
end
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
55
63
|
So. Add hooks. To any Ruby method. That's pretty damn awesome, where I come form. I SAID "FORM," son!
|
56
64
|
|
57
65
|
But, as they say, "love is only a feeling." So spoon like there's no tomorrow.
|
@@ -60,7 +68,7 @@ But, as they say, "love is only a feeling." So spoon like there's no tomorrow.
|
|
60
68
|
|
61
69
|
Because ActiveModel callbacks are just so damn delightful, I've added some fun conditional sugar to match their wonderful. So g'head and add some `:if` conditions to your callbacks:
|
62
70
|
|
63
|
-
```
|
71
|
+
```
|
64
72
|
class User
|
65
73
|
before :love_on_the_rocks, :add_ice, :if => :no_ice?
|
66
74
|
|
@@ -81,36 +89,26 @@ end
|
|
81
89
|
|
82
90
|
Conditional callbacks also support `:unless`, just like their ActiveModel ancestors. Or should I say "inspiritors?" Is that word? Shut up, of course it is. Anyway:
|
83
91
|
|
84
|
-
```
|
92
|
+
```
|
85
93
|
class User
|
86
|
-
before :love_on_the_rocks, :add_ice, :unless => :
|
94
|
+
before :love_on_the_rocks, :add_ice, :unless => :in_tys_mazada?
|
87
95
|
|
88
96
|
def not_in_tys_mazada?
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
protected
|
93
|
-
def add_ice
|
94
|
-
Ice.create!
|
97
|
+
(mazda = User.find_by_name("Ty").car) && mazda.has_rad_bass?
|
95
98
|
end
|
96
99
|
end
|
97
100
|
```
|
98
101
|
|
99
|
-
And to recap! Just as with the believing-in-things-called-love example, both could be re-written
|
102
|
+
And to recap! Just as with the believing-in-things-called-love example, both could be re-written along these lines:
|
100
103
|
|
101
|
-
```ruby
|
102
|
-
before_love_on_the_rocks :add_ice, :if => :no_ice?
|
103
104
|
```
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
105
|
+
before_love_on_the_rocks :add_ice, :if => :no_ice?
|
106
|
+
# or
|
107
|
+
hooks do
|
108
|
+
before :love_on_the_rocks, :add_if, :if => :no_ice?
|
109
|
+
end
|
109
110
|
```
|
110
111
|
|
111
|
-
respectively.
|
112
|
-
|
113
112
|
HAPPY **CALLING-OF-THE-BACK**, FRIENDS!
|
114
113
|
|
115
|
-
|
116
114
|
Copyright © 2012 Delightful Widgets Inc. No warranty so don't sue me or my company THANKS!
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/big_spoon.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "big_spoon"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Flip Sasser"]
|
12
|
-
s.date = "2012-08-
|
12
|
+
s.date = "2012-08-14"
|
13
13
|
s.description = "\n BigSpoon will add a hooks method to every class. Call that method with a block and add all kinds of fun hooks before and after your methods.\n "
|
14
14
|
s.email = "flip@x451.com"
|
15
15
|
s.extra_rdoc_files = [
|
data/lib/big_spoon/hook.rb
CHANGED
@@ -48,7 +48,7 @@ module BigSpoon
|
|
48
48
|
alias :#{original_method} :#{method_to_hook}
|
49
49
|
def #{hooked_method}(*args)
|
50
50
|
Hook.for(self.class).execute_before(:#{method_to_hook}, self)
|
51
|
-
result = #{original_method}
|
51
|
+
result = #{original_method}(*args)
|
52
52
|
Hook.for(self.class).execute_after(:#{method_to_hook}, self)
|
53
53
|
result
|
54
54
|
end
|
data/lib/big_spoon.rb
CHANGED
@@ -19,12 +19,16 @@ module BigSpoon
|
|
19
19
|
end
|
20
20
|
@hooks
|
21
21
|
end # `hooks` method
|
22
|
-
|
22
|
+
|
23
23
|
private
|
24
24
|
def method_missing(method_name, *args)
|
25
25
|
case method_name.to_s
|
26
|
+
when 'after'
|
27
|
+
hooks.after *args
|
26
28
|
when /^after_(.+)$/
|
27
29
|
hooks.after $1, *args
|
30
|
+
when 'before'
|
31
|
+
hooks.before *args
|
28
32
|
when /^before_(.+)$/
|
29
33
|
hooks.before $1, *args
|
30
34
|
else
|
data/spec/lib/big_spoon_spec.rb
CHANGED
@@ -13,6 +13,22 @@ class BigSpoonTest
|
|
13
13
|
:bar
|
14
14
|
end
|
15
15
|
|
16
|
+
def i_accept_one(argument)
|
17
|
+
puts argument
|
18
|
+
end
|
19
|
+
|
20
|
+
def i_accept_many(*arguments)
|
21
|
+
puts arguments
|
22
|
+
end
|
23
|
+
|
24
|
+
def i_might_accept_one(argument = nil)
|
25
|
+
puts argument
|
26
|
+
end
|
27
|
+
|
28
|
+
def raise_sommat
|
29
|
+
raise "This method will never look the same! EVER!"
|
30
|
+
end
|
31
|
+
|
16
32
|
private
|
17
33
|
def by_all_means_hook
|
18
34
|
true
|
@@ -22,7 +38,7 @@ class BigSpoonTest
|
|
22
38
|
false
|
23
39
|
end
|
24
40
|
|
25
|
-
(1..
|
41
|
+
(1..20).each do |index|
|
26
42
|
define_method("hook_#{index}") { "hook_#{index}"}
|
27
43
|
end
|
28
44
|
end
|
@@ -116,4 +132,31 @@ describe BigSpoon do
|
|
116
132
|
BigSpoonTest.before_foo! :hook_8
|
117
133
|
@big_spoon_test.foo!
|
118
134
|
end
|
135
|
+
|
136
|
+
it "should handle a set number of arguments in methods" do
|
137
|
+
BigSpoonTest.before :i_accept_one, :hook_9
|
138
|
+
@big_spoon_test.should_receive(:puts).with("ohai")
|
139
|
+
@big_spoon_test.i_accept_one("ohai")
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should handle an arbitrary number of arguments in methods" do
|
143
|
+
BigSpoonTest.before :i_accept_many, :hook_10
|
144
|
+
@big_spoon_test.should_receive(:puts).with(["ohai", "i'll be an array", "someday"])
|
145
|
+
@big_spoon_test.i_accept_many("ohai", "i'll be an array", "someday")
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should handle an option argument" do
|
149
|
+
BigSpoonTest.after :i_might_accept_one, :hook_11
|
150
|
+
@big_spoon_test.should_receive(:puts).with(nil)
|
151
|
+
@big_spoon_test.i_might_accept_one
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should debug clearly when a method throws an error" do
|
155
|
+
BigSpoonTest.after :raise_sommat, :hook_12
|
156
|
+
begin
|
157
|
+
@big_spoon_test.raise_sommat
|
158
|
+
rescue Exception => error
|
159
|
+
$!.backtrace.first.should =~ /:\d+\:in `raise_sommat'/
|
160
|
+
end
|
161
|
+
end
|
119
162
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: big_spoon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.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-08-
|
12
|
+
date: 2012-08-14 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! "\n BigSpoon will add a hooks method to every class. Call that
|
15
15
|
method with a block and add all kinds of fun hooks before and after your methods.\n
|
@@ -49,7 +49,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
49
49
|
version: '0'
|
50
50
|
segments:
|
51
51
|
- 0
|
52
|
-
hash:
|
52
|
+
hash: 2835356473338463026
|
53
53
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
54
|
none: false
|
55
55
|
requirements:
|