after_do 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5d5697c2f0c8130887073ed0072678789e8602cc
4
- data.tar.gz: 40ad3b18353a8233045639effb09e95df96ab3b7
3
+ metadata.gz: ef369cfcfc9f7d0df1898cb7a19063c54d8197ab
4
+ data.tar.gz: 5e9cb593b171bdb4847f92aaa6ab8bf12baa3186
5
5
  SHA512:
6
- metadata.gz: 404f4d82231b298a86d8e6699054dd0ca799a1b0e8ad85690ba2d308bb3b2d6b44564862da3440306f4ddde4ccb5e4a86f7e468a4a61cd22217c8a0ce99ac81e
7
- data.tar.gz: e6e641a679300989f91a1185d546c2dca3ac2b3d31dbdbf5b6df7ed01bb8f3a690c99bf155bc104ef0f671bf3c25fca3dcb2bf6e769a320c066cc906a6f59020
6
+ metadata.gz: 8d27b6cd8f09cad52b0b721c247c598c18178631133b92f730dcaa8b497acbf78a49d5130f9c48cc79528557a4ee0fb3b222b1783461ba26d030d43bff2b2088
7
+ data.tar.gz: 7af1a95ded2526a59b80d8bf7059df8906844d64ec9755c831170e5dee3e86e62040d08b4586e01381678449563d1a0579807fce67c722fcd81919d3a479ed3f
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-2.0.0-p353
1
+ ruby-2.1.1
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # after_do [![Gem Version](https://badge.fury.io/rb/after_do.png)](http://badge.fury.io/rb/after_do)[![Build Status](https://travis-ci.org/PragTob/after_do.png?branch=master)](https://travis-ci.org/PragTob/after_do)[![Code Climate](https://codeclimate.com/github/PragTob/after_do.png)](https://codeclimate.com/github/PragTob/after_do)[![Coverage Status](https://coveralls.io/repos/PragTob/after_do/badge.png)](https://coveralls.io/r/PragTob/after_do)
2
2
 
3
- after_do is simple gem, that helps you fight cross-cutting concerns with an approach similar to Aspect Oriented Programming (AOP). after_do allows you to execute blocks (callbacks) after/before specific methods of a class or a module are called.
3
+ after_do is a simple gem, that helps you fight cross-cutting concerns with an approach similar to Aspect Oriented Programming (AOP). after_do allows you to execute blocks (callbacks) after/before specific methods of a class or a module are called.
4
4
 
5
5
  If the class extends `AfterDo` you can simply do this by
6
6
 
@@ -10,14 +10,15 @@ MyClass.after :some_method do whatever_you_want end
10
10
 
11
11
  Some facts about after_do:
12
12
 
13
- * no external runtime dependencies
13
+ * no runtime dependencies
14
14
  * small code base: code is around 120 lines of code with blank lines, comments and everything - simplecov reports less than 60 relevant lines of code
15
15
  * simple DSL
16
16
  * no monkey patching
17
17
 
18
18
  ## Why would you want to do this?
19
19
  Well to fight cross-cutting concerns. These are concerns in an applications that apply to multiple objects (e.g. they cross-cut).
20
- A popular example is logging - you might want to log multiple actions of different classes but logging is not the primary concern of the class in question. With logging you litter all your code with logging statements - that concern is spread over many files and adds unnecessary noise to them. With after_do you could put all the logging in one file. Other use cases include gathering business statistics or redrawing timing of elements.
20
+ A popular example is logging - you might want to log multiple actions of different classes but logging is not the primary concern of the class in question. With logging you litter all your code with logging statements - that concern is spread over many files and adds unnecessary noise to them.
21
+ With after_do you could put all the logging in one file. Other use cases include gathering business statistics or redrawing timing of elements.
21
22
  This should generally not be done to alter behavior of the class and its instances - this makes programs more confusing rather than easier to understand.
22
23
 
23
24
  The idea for this is inspired by Aspect Oriented Programming - e.g. do something when specific methods are executed. However I doubt that this formally fulfills the lingo (join points, aspects, advice...)
@@ -35,10 +36,14 @@ And then execute:
35
36
  Or install it yourself as:
36
37
 
37
38
  $ gem install after_do
39
+
40
+ And then you have to require the gem before you can use it:
41
+
42
+ require 'after_do'
38
43
 
39
44
  ## Usage
40
45
 
41
- This section is dedicated to show of the general usage and effects of after_do. You can also check out the samples directory for some samples or the specs in the spec folder.
46
+ This section is dedicated to show the general usage and effects of after_do. You can also check out the [samples directory](https://github.com/PragTob/after_do/tree/master/samples) or the [specs](https://github.com/PragTob/after_do/blob/master/spec/after_do_spec.rb) in the spec folder.
42
47
 
43
48
  ### General usage
44
49
 
@@ -72,22 +77,8 @@ dog2.bark
72
77
  # I just heard a dog bark!
73
78
  # Woooof
74
79
  # I just heard a dog bark!
75
-
76
- ```
77
-
78
- ### How does it work?
79
-
80
- When you attach a callback to a method with after_do what it basically does is it creates a copy of that method and then redefines the method to basically look like this (pseudo code):
81
-
82
- ```ruby
83
- execute_before_callbacks
84
- return_value = original_method
85
- execute_after_callbacks
86
- return_value
87
80
  ```
88
81
 
89
- To do this some helper methods are defined in the AfterDo module. As classes have to extend the AfterDo module all the methods that you are not supposed to call yourself are prefixed with `_after_do_` to minimize the risk of method name clashes. The only not prefixed method are `after`, `before` and `remove_all_callbacks`.
90
-
91
82
  ### Getting a hold of the method arguments and the object
92
83
 
93
84
  With after_do both the arguments to the method you are attaching the callback to and the object for which the callback is executed are passed into the callback block.
@@ -175,9 +166,47 @@ b = B.new
175
166
  b.a #prints out: a was called
176
167
  ```
177
168
 
169
+ ### Working with modules
170
+
171
+ after_do works with modules just like it works with classes from version 0.3.0 onwards. E.g. you can just do:
172
+
173
+ ```ruby
174
+ class MyClass
175
+ include MyModule
176
+ # ....
177
+ end
178
+
179
+ MyModule.extend AfterDo
180
+ MyModule.after :some_method do cool_stuff end
181
+
182
+ MyClass.new.some_method # triggers callback
183
+ ```
184
+
185
+ ### Working with module/class/singleton methods
186
+
187
+ after_do also works with module/class/singleton methods whatever you want to call them, e.g. with `MyModule.method`, thanks to ruby's awesome object/class system. You just have to attach the callbacks to the singleton class of the object (because that's where the "class side" methods are defined).
188
+
189
+ Take a look:
190
+
191
+ ```ruby
192
+ module M
193
+ def self.magic
194
+ puts 'magic'
195
+ end
196
+ end
197
+
198
+ M.singleton_class.extend AfterDo
199
+ M.singleton_class.after :magic do puts 'after_do is pure magic' end
200
+
201
+ M.magic
202
+ # Output is:
203
+ magic
204
+ after_do is pure magic
205
+ ```
206
+
178
207
  ### Usage from within a class
179
208
 
180
- If you got some repetitive tasks, that needs to be done after/before a lot of methods in a class then you can also use after_do for this. This works a bit like `before_action`/`after_action` which you might know from Ruby on Rails.
209
+ If you got some repetitive tasks, that need to be done after/before a lot of methods in a class then you can also use after_do for this. This works a bit like `before_action`/`after_action` (or *_filter in the Rails 3 lingo) which you might know from Ruby on Rails.
181
210
 
182
211
  E.g. like this:
183
212
 
@@ -193,21 +222,6 @@ end
193
222
 
194
223
  Check out the [within class sample](https://github.com/PragTob/after_do/blob/master/samples/within_class.rb) for a more complete example.
195
224
 
196
- ### Working with modules
197
-
198
- after_do works with modules just like it works with classes from version 0.3.0 onwards. E.g. you can just do:
199
-
200
- ```ruby
201
- class MyClass
202
- include MyModule
203
- # ....
204
- end
205
-
206
- MyModule.extend AfterDo
207
- MyModule.after :some_method do cool_stuff end
208
-
209
- MyClass.new.some_method # triggers callback
210
- ```
211
225
 
212
226
  ### Removing callbacks
213
227
 
@@ -217,7 +231,7 @@ You can remove all callbacks you added to a class by doing:
217
231
  MyClass.remove_all_callbacks
218
232
  ```
219
233
 
220
- Note that this not remove callbacks defined in super classes.
234
+ Note that this not remove callbacks defined in super/sub classes.
221
235
 
222
236
  ### Errors
223
237
 
@@ -225,6 +239,19 @@ There are some custom errors that after_do throws. When you try to add a callbac
225
239
 
226
240
  When an error occurs during one of the callbacks that are attached to a method it will throw `AfterDo::CallbackError` with information about the original error and where the block/callback causing this error was defined to help pinpoint the error.
227
241
 
242
+ ### How does it work?
243
+
244
+ When you attach a callback to a method with after_do what it basically does is it creates a copy of that method and then redefines the method to basically look like this (pseudo code):
245
+
246
+ ```ruby
247
+ execute_before_callbacks
248
+ return_value = original_method
249
+ execute_after_callbacks
250
+ return_value
251
+ ```
252
+
253
+ To do this some helper methods are defined in the AfterDo module. As classes have to extend the AfterDo module all the methods that you are not supposed to call yourself are prefixed with `_after_do_` to minimize the risk of method name clashes. The only not prefixed method are `after`, `before` and `remove_all_callbacks`.
254
+
228
255
 
229
256
  ## Is there a before method?
230
257
 
@@ -236,12 +263,11 @@ MyClass.before :a_method do so_much end
236
263
 
237
264
  Check out the [before sample](https://github.com/PragTob/after_do/blob/master/samples/before.rb).
238
265
 
239
-
240
266
  ### Method granularity
241
267
 
242
- after_do works on the granularity of methods. That means that you can only attach callbacks to methods. This is no problem however, since if it's your code you can always define new methods. E.g. you want to attach callbacks to the end of some operation that happens in the middle of a method just define a new method for that piece of code.
268
+ after_do works on the granularity of methods. That means that you can only attach callbacks to methods. This is no problem however, since if it's your code you can always define new methods. E.g. if you want to attach callbacks to the end of some operation that happens in the middle of a method just define a new method for that piece of code.
243
269
 
244
- I sometimes do this for evaluating the block, as I want to do something when that block finished evaluating so I define a method `eval_block` wherein I just evaluate the block.
270
+ I sometimes do this for evaluating a block, as I want to do something when that block finished evaluating so I define a method `eval_block` wherein I just evaluate the block.
245
271
 
246
272
  ## Is this a good idea?
247
273
 
data/lib/after_do.rb CHANGED
@@ -80,7 +80,7 @@ module AfterDo
80
80
  end
81
81
 
82
82
  def _after_do_raise_no_method_error(method)
83
- raise NonExistingMethodError, "There is no method #{method} on #{self} to attach a block to with AfterDo"
83
+ raise NonExistingMethodError, "There is no method #{method} on #{self} to attach a block to with after_do"
84
84
  end
85
85
 
86
86
  def _after_do_aliased_name(symbol)
@@ -110,9 +110,9 @@ module AfterDo
110
110
 
111
111
  def _after_do_execute_callback(block, method, object, *args)
112
112
  begin
113
- block.call *args, object
113
+ block.call(*args, object)
114
114
  rescue Exception => error
115
- raise CallbackError, "A callback block for method #{method} on the instance #{self} with the following arguments: #{args.join(', ')} defined in the file #{block.source_location[0]} in line #{block.source_location[1]} resulted in the following error: #{error.class}: #{error.message} and this backtrace:\n #{error.backtrace.join("\n")}"
115
+ raise CallbackError, "A #{error.class}: #{error.message} was raised during an after_do callback block for method '#{method}' on the instance #{self.inspect} with the following arguments: #{args.join(', ')} defined in the file #{block.source_location[0]} in line #{block.source_location[1]}. This is the backtrace of the #{error.class}: \n #{error.backtrace.join("\n")}"
116
116
  end
117
117
  end
118
118
  end
@@ -1,4 +1,4 @@
1
1
  module AfterDo
2
2
  # ::nodoc::
3
- VERSION = '0.3.0'
3
+ VERSION = '0.3.1'
4
4
  end
@@ -0,0 +1,13 @@
1
+ require 'after_do'
2
+
3
+ module M
4
+ def self.magic
5
+ puts 'magic'
6
+ end
7
+ end
8
+
9
+ M.singleton_class.extend AfterDo
10
+ M.singleton_class.after :magic do puts 'after_do is pure magic' end
11
+
12
+ M.magic
13
+ M.magic
@@ -125,11 +125,11 @@ describe AfterDo do
125
125
  end
126
126
 
127
127
  it 'mentions the error raised' do
128
- expect_call_back_error /StandardError/
128
+ expect_call_back_error(/StandardError/)
129
129
  end
130
130
 
131
131
  it 'mentions the method called' do
132
- expect_call_back_error /zero/
132
+ expect_call_back_error(/zero/)
133
133
  end
134
134
 
135
135
  it 'mentions the file the error was raised in' do
@@ -137,7 +137,7 @@ describe AfterDo do
137
137
  end
138
138
 
139
139
  it 'mentions the original error message' do
140
- expect_call_back_error /silly message/
140
+ expect_call_back_error(/silly message/)
141
141
  end
142
142
  end
143
143
  end
@@ -363,6 +363,28 @@ describe AfterDo do
363
363
 
364
364
  end
365
365
  end
366
+
367
+ describe 'module/class/singleton methods' do
368
+ def singleton_module
369
+ Module.new do
370
+ def self.my_singleton_method
371
+ 'singleton_method'
372
+ end
373
+ end
374
+ end
375
+
376
+ it 'works when you use the singleton_class' do
377
+ my_module = singleton_module
378
+ my_module.singleton_class.extend AfterDo
379
+ my_module.singleton_class.send callback_adder, :my_singleton_method do
380
+ mockie.call
381
+ end
382
+ my_module.my_singleton_method
383
+ expect(mockie).to have_received(:call)
384
+ end
385
+
386
+ end
387
+
366
388
  end
367
389
 
368
390
  it_behaves_like 'calling callbacks', :after
@@ -392,4 +414,4 @@ describe AfterDo do
392
414
  dummy_instance.zero
393
415
  end
394
416
  end
395
- end
417
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: after_do
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Pfeiffer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-19 00:00:00.000000000 Z
11
+ date: 2014-03-27 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: after_do is a gem that let's you execute a block of your choice after
14
14
  or before a specific method is called on a class. This is inspired by Aspect Oriented
@@ -19,10 +19,10 @@ executables: []
19
19
  extensions: []
20
20
  extra_rdoc_files: []
21
21
  files:
22
- - .gitignore
23
- - .ruby-gemset
24
- - .ruby-version
25
- - .travis.yml
22
+ - ".gitignore"
23
+ - ".ruby-gemset"
24
+ - ".ruby-version"
25
+ - ".travis.yml"
26
26
  - Gemfile
27
27
  - Guardfile
28
28
  - LICENSE.txt
@@ -36,6 +36,7 @@ files:
36
36
  - samples/error_in_callback.rb
37
37
  - samples/getting_a_hold.rb
38
38
  - samples/inheritance.rb
39
+ - samples/singleton.rb
39
40
  - samples/with_module.rb
40
41
  - samples/within_class.rb
41
42
  - spec/after_do_spec.rb
@@ -50,17 +51,17 @@ require_paths:
50
51
  - lib
51
52
  required_ruby_version: !ruby/object:Gem::Requirement
52
53
  requirements:
53
- - - '>='
54
+ - - ">="
54
55
  - !ruby/object:Gem::Version
55
56
  version: '0'
56
57
  required_rubygems_version: !ruby/object:Gem::Requirement
57
58
  requirements:
58
- - - '>='
59
+ - - ">="
59
60
  - !ruby/object:Gem::Version
60
61
  version: '0'
61
62
  requirements: []
62
63
  rubyforge_project:
63
- rubygems_version: 2.1.11
64
+ rubygems_version: 2.2.2
64
65
  signing_key:
65
66
  specification_version: 4
66
67
  summary: after_do allows you to add simple after/before hooks to methods