super_callbacks 1.0.3 → 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.
- checksums.yaml +4 -4
- data/README.md +439 -394
- data/lib/super_callbacks/version.rb +1 -1
- data/lib/super_callbacks.rb +254 -217
- data/super_callbacks.gemspec +2 -2
- metadata +8 -7
data/README.md
CHANGED
@@ -1,394 +1,439 @@
|
|
1
|
-
# SuperCallbacks
|
2
|
-
|
3
|
-
[](https://travis-ci.org/jrpolidario/super_callbacks)
|
4
|
-
[](https://badge.fury.io/rb/super_callbacks)
|
5
|
-
|
6
|
-
* Allows `before` and `after` callbacks to any Class.
|
7
|
-
* Supports
|
8
|
-
* Supports
|
9
|
-
* Supports
|
10
|
-
|
11
|
-
|
12
|
-
*
|
13
|
-
*
|
14
|
-
*
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
56
|
-
|
57
|
-
|
58
|
-
foo.
|
59
|
-
|
60
|
-
# => 'bar!'
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
end
|
77
|
-
|
78
|
-
|
79
|
-
foo.
|
80
|
-
|
81
|
-
# => '
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
end
|
102
|
-
|
103
|
-
|
104
|
-
foo.
|
105
|
-
|
106
|
-
# => '
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
before :bar
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
end
|
137
|
-
|
138
|
-
|
139
|
-
foo.
|
140
|
-
|
141
|
-
# => '
|
142
|
-
# => 'bar
|
143
|
-
# => 'bar!'
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
puts "@bar
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
end
|
173
|
-
|
174
|
-
|
175
|
-
foo
|
176
|
-
|
177
|
-
# => '@bar
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
# => 'baz
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
#
|
200
|
-
#
|
201
|
-
#
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
end
|
208
|
-
|
209
|
-
|
210
|
-
monster
|
211
|
-
monster.hp
|
212
|
-
monster.hp -= 1 #
|
213
|
-
monster.hp -= 1 #
|
214
|
-
monster.hp -= 1 #
|
215
|
-
monster.hp -= 1 #
|
216
|
-
#
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
end
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
end
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
# => 'before bar
|
281
|
-
# => 'before bar
|
282
|
-
# => 'before bar
|
283
|
-
# => 'bar
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
# => 'before bar
|
288
|
-
# => 'bar!'
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
end
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
end
|
315
|
-
|
316
|
-
|
317
|
-
foo.
|
318
|
-
|
319
|
-
# => 'bar!'
|
320
|
-
|
321
|
-
|
322
|
-
sub_foo.
|
323
|
-
|
324
|
-
# => '
|
325
|
-
# => 'bar
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
end
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
end
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
1
|
+
# SuperCallbacks
|
2
|
+
|
3
|
+
[](https://travis-ci.org/jrpolidario/super_callbacks)
|
4
|
+
[](https://badge.fury.io/rb/super_callbacks)
|
5
|
+
|
6
|
+
* Allows `before` and `after` callbacks to any Class.
|
7
|
+
* Supports "dirty" checking of instance variables changes
|
8
|
+
* Supports both class and instance level callbacks
|
9
|
+
* Supports conditional callbacks
|
10
|
+
* Supports inherited callbacks; hence named "Super", get it? :D haha!
|
11
|
+
---
|
12
|
+
* Focuses on performance and flexibility as intended primarily for game development, and event-driven apps
|
13
|
+
* Standalone; no other gem dependencies
|
14
|
+
* `super_callbacks` is the upgraded version of my other repo [`dragonruby_callbacks`](https://github.com/jrpolidario/dragonruby_callbacks)
|
15
|
+
* Heavily influenced by [Rails' ActiveSupport::Callbacks](https://api.rubyonrails.org/classes/ActiveSupport/Callbacks.html)
|
16
|
+
|
17
|
+
## Dependencies
|
18
|
+
|
19
|
+
* **Ruby ~> 2.0**
|
20
|
+
|
21
|
+
## Installation
|
22
|
+
|
23
|
+
Add this line to your application's Gemfile:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
gem 'super_callbacks', '~> 1.1'
|
27
|
+
```
|
28
|
+
|
29
|
+
And then execute:
|
30
|
+
|
31
|
+
$ bundle
|
32
|
+
|
33
|
+
Or install it yourself as:
|
34
|
+
|
35
|
+
$ gem install super_callbacks
|
36
|
+
|
37
|
+
## Usage
|
38
|
+
|
39
|
+
### Example 1 (Block Mode)
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
require 'super_callbacks'
|
43
|
+
|
44
|
+
class Foo
|
45
|
+
# add this line inside your Class file/s
|
46
|
+
include SuperCallbacks
|
47
|
+
|
48
|
+
# add this block of lines
|
49
|
+
before :bar do
|
50
|
+
puts 'before bar!'
|
51
|
+
end
|
52
|
+
|
53
|
+
def bar
|
54
|
+
puts 'bar!'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
foo = Foo.new
|
59
|
+
foo.bar
|
60
|
+
# => 'before bar!'
|
61
|
+
# => 'bar!'
|
62
|
+
```
|
63
|
+
|
64
|
+
*Notice above that the before block gets called first before the method `bar`*
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
class Foo
|
68
|
+
include SuperCallbacks
|
69
|
+
|
70
|
+
after :bar do
|
71
|
+
puts 'after bar!'
|
72
|
+
end
|
73
|
+
|
74
|
+
def bar
|
75
|
+
puts 'bar!'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
foo = Foo.new
|
80
|
+
foo.bar
|
81
|
+
# => 'bar!'
|
82
|
+
# => 'after bar!'
|
83
|
+
```
|
84
|
+
|
85
|
+
*Notice above that the after block gets called after the method `bar`*
|
86
|
+
|
87
|
+
### Example 2 (Method Calling)
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
class Foo
|
91
|
+
include SuperCallbacks
|
92
|
+
|
93
|
+
before :bar, :baz
|
94
|
+
|
95
|
+
def bar
|
96
|
+
puts 'bar!'
|
97
|
+
end
|
98
|
+
|
99
|
+
def baz
|
100
|
+
puts 'baz!'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
foo = Foo.new
|
105
|
+
foo.bar
|
106
|
+
# => 'baz!'
|
107
|
+
# => 'bar!'
|
108
|
+
```
|
109
|
+
|
110
|
+
*Notice above that you can also call another method instead of supplying a block.*
|
111
|
+
|
112
|
+
*Above uses `before`, but works similarly with `after`*
|
113
|
+
|
114
|
+
### Example 3 (Multiple Callbacks)
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
class Foo
|
118
|
+
include SuperCallbacks
|
119
|
+
|
120
|
+
before :bar, :baz_1
|
121
|
+
before :bar do
|
122
|
+
puts 'baz 2!'
|
123
|
+
end
|
124
|
+
before :bar, :baz_3
|
125
|
+
|
126
|
+
def bar
|
127
|
+
puts 'bar!'
|
128
|
+
end
|
129
|
+
|
130
|
+
def baz_1
|
131
|
+
puts 'baz 1!'
|
132
|
+
end
|
133
|
+
|
134
|
+
def baz_3
|
135
|
+
puts 'baz 3!'
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
foo = Foo.new
|
140
|
+
foo.bar
|
141
|
+
# => 'baz 1!'
|
142
|
+
# => 'bar 2!'
|
143
|
+
# => 'bar 3!'
|
144
|
+
# => 'bar!'
|
145
|
+
```
|
146
|
+
|
147
|
+
*Notice above multiple callbacks are supported, and that they are called in firt-come-first-served order.*
|
148
|
+
|
149
|
+
*Above uses `before`, but works similarly with `after`*
|
150
|
+
|
151
|
+
### Example 4 (Setter Method Callbacks)
|
152
|
+
|
153
|
+
> This is the primary reason why I made this: to handle "change-dependent" logic in my game engine
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
class Foo
|
157
|
+
include SuperCallbacks
|
158
|
+
|
159
|
+
attr_accessor :bar
|
160
|
+
|
161
|
+
before :bar= do |arg|
|
162
|
+
puts "@bar currently has a value of #{@bar}"
|
163
|
+
puts "@bar will have a new value of #{arg}"
|
164
|
+
end
|
165
|
+
|
166
|
+
before :baz do |arg1, arg2|
|
167
|
+
puts "baz will be called with arguments #{arg1}, #{arg2}"
|
168
|
+
end
|
169
|
+
|
170
|
+
def baz(x, y)
|
171
|
+
puts 'baz has been called!'
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
foo = Foo.new
|
176
|
+
foo.bar = 5
|
177
|
+
# => '@bar currently has a value of '
|
178
|
+
# => '@bar will have a new value of 5'
|
179
|
+
puts foo.bar
|
180
|
+
# => 5
|
181
|
+
|
182
|
+
foo.baz(1, 2)
|
183
|
+
# => 'baz will be called with arguments 1, 2'
|
184
|
+
# => 'baz has been called!'
|
185
|
+
```
|
186
|
+
|
187
|
+
*Above uses `before`, but works similarly with `after`*
|
188
|
+
|
189
|
+
### Example 5 (Conditional Callbacks)
|
190
|
+
|
191
|
+
```ruby
|
192
|
+
class Monster
|
193
|
+
include SuperCallbacks
|
194
|
+
|
195
|
+
attr_accessor :hp
|
196
|
+
|
197
|
+
after :hp=, :despawn, if: -> (arg) { @hp == 0 }
|
198
|
+
|
199
|
+
# above is just equivalently:
|
200
|
+
# after :hp= do |arg|
|
201
|
+
# despawn if @hp == 0
|
202
|
+
# end
|
203
|
+
|
204
|
+
def despawn
|
205
|
+
puts 'despawning!'
|
206
|
+
# do something here, like say removing the Monster from the world
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
monster = Monster.new
|
211
|
+
monster.hp = 5
|
212
|
+
monster.hp -= 1 # 4
|
213
|
+
monster.hp -= 1 # 3
|
214
|
+
monster.hp -= 1 # 2
|
215
|
+
monster.hp -= 1 # 1
|
216
|
+
monster.hp -= 1 # hp is now 0, so despawn!
|
217
|
+
# => despawning!
|
218
|
+
```
|
219
|
+
|
220
|
+
*Above uses `after`, but works similarly with `before`*
|
221
|
+
|
222
|
+
### Example 6 (Pseudo-Skipping Callbacks)
|
223
|
+
|
224
|
+
* via Ruby's [`instance_variable_get`](https://ruby-doc.org/core-1.9.1/Object.html#method-i-instance_variable_get) and [`instance_variable_set`](https://ruby-doc.org/core-1.9.1/Object.html#method-i-instance_variable_set)
|
225
|
+
|
226
|
+
```ruby
|
227
|
+
class Foo
|
228
|
+
include SuperCallbacks
|
229
|
+
|
230
|
+
attr_accessor :bar
|
231
|
+
|
232
|
+
before :bar= do |arg|
|
233
|
+
puts 'before bar= is called!'
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
foo = Foo.new
|
238
|
+
|
239
|
+
# normal way (callbacks are called):
|
240
|
+
foo.bar = 'somevalue'
|
241
|
+
# => 'before_bar= is called!'
|
242
|
+
|
243
|
+
# but to "pseudo" skip all callbacks, and directly manipulate the instance variable value:
|
244
|
+
foo.instance_variable_set(:@bar, 'somevalue')
|
245
|
+
```
|
246
|
+
|
247
|
+
*At the moment, I am not compelled (yet?) to fully support skipping callbacks because I do not want to pollute the DSL and I do not find myself yet needing such behaviour, because the callbacks are there for "integrity". If I really want the callbacks conditional, I'll just use the conditional argument.*
|
248
|
+
|
249
|
+
### Example 7 (Class and Instance Level Callbacks)
|
250
|
+
|
251
|
+
```ruby
|
252
|
+
class Foo
|
253
|
+
include SuperCallbacks
|
254
|
+
|
255
|
+
before :bar do
|
256
|
+
puts 'before bar 1!'
|
257
|
+
end
|
258
|
+
|
259
|
+
before :bar do
|
260
|
+
puts 'before bar 2!'
|
261
|
+
end
|
262
|
+
|
263
|
+
def bar
|
264
|
+
puts 'bar!'
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
foo_1 = Foo.new
|
269
|
+
foo_2 = Foo.new
|
270
|
+
|
271
|
+
foo_1.before :bar do
|
272
|
+
puts 'before bar 3'
|
273
|
+
end
|
274
|
+
|
275
|
+
foo_1.before :bar do
|
276
|
+
puts 'before bar 4'
|
277
|
+
end
|
278
|
+
|
279
|
+
foo_1.bar
|
280
|
+
# => 'before bar 1!'
|
281
|
+
# => 'before bar 2!'
|
282
|
+
# => 'before bar 3'
|
283
|
+
# => 'before bar 4'
|
284
|
+
# => 'bar!'
|
285
|
+
|
286
|
+
foo_2.bar
|
287
|
+
# => 'before bar 1!'
|
288
|
+
# => 'before bar 2!'
|
289
|
+
# => 'bar!'
|
290
|
+
```
|
291
|
+
|
292
|
+
*Notice above that foo_1 and foo_2 both call the class-level callbacks, while they have independent (not-shared) instance-level callbacks defined. Order of execution is class-level first then instance-level, of which defined callbacks are then in order of first-come-first-serve.*
|
293
|
+
|
294
|
+
*Above uses `before`, but works similarly with `after`*
|
295
|
+
|
296
|
+
### Example 8 (Inherited Callbacks)
|
297
|
+
|
298
|
+
```ruby
|
299
|
+
class Foo
|
300
|
+
include SuperCallbacks
|
301
|
+
|
302
|
+
before :bar do
|
303
|
+
puts 'Foo: before bar 1!'
|
304
|
+
end
|
305
|
+
|
306
|
+
def bar
|
307
|
+
puts 'bar!'
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
class SubFoo < Foo
|
312
|
+
before :bar do
|
313
|
+
puts 'SubFoo: bar'
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
foo = Foo.new
|
318
|
+
foo.bar
|
319
|
+
# => 'Foo: before bar 1!'
|
320
|
+
# => 'bar!'
|
321
|
+
|
322
|
+
sub_foo = SubFoo.new
|
323
|
+
sub_foo.bar
|
324
|
+
# => 'Foo: before bar 1!'
|
325
|
+
# => 'SubFoo: bar'
|
326
|
+
# => 'bar!'
|
327
|
+
```
|
328
|
+
|
329
|
+
*Notice above `sub_foo` calls both `before` callbacks defined in `Foo` and `SubFoo`, because SubFoo inherits from Foo. Callbacks are called in order of ancestors descending; meaning it starts calling the top-level ancestor superclass callbacks, and then calling its subclass callbacks, until it reaches the instance's class callbacks*
|
330
|
+
|
331
|
+
*Above uses `before`, but works similarly with `after`*
|
332
|
+
|
333
|
+
### Example 9 (Requiring Method To Be Defined)
|
334
|
+
|
335
|
+
```ruby
|
336
|
+
class Foo
|
337
|
+
include SuperCallbacks
|
338
|
+
|
339
|
+
after! :bar do
|
340
|
+
puts 'after bar!'
|
341
|
+
end
|
342
|
+
|
343
|
+
def bar
|
344
|
+
puts 'bar!'
|
345
|
+
end
|
346
|
+
end
|
347
|
+
# => ArgumentError: `bar` is not or not yet defined for Foo
|
348
|
+
|
349
|
+
class Foo
|
350
|
+
include SuperCallbacks
|
351
|
+
|
352
|
+
def bar
|
353
|
+
puts 'bar!'
|
354
|
+
end
|
355
|
+
|
356
|
+
after! :bar do
|
357
|
+
puts 'after bar!'
|
358
|
+
end
|
359
|
+
end
|
360
|
+
# => [NO ERRORS]
|
361
|
+
```
|
362
|
+
|
363
|
+
*From above, sometimes I noticed that I forgot to define a method! So the bang `!` version is just basically like `after` except that this raises an error if `method_name` is not defined or not yet defined (at the time `after!` is called). This works perfect with `attr_accesors` I normally put them at the top of the lines of a Class, and so I can now safely call `before!` or `after!` because I am sure that I already defined everything I needed to define. If I forgot something then, this `before!` would raise an error and alert me, and not silently failing. Helps debugging :)*
|
364
|
+
|
365
|
+
*Above uses `after!`, but works similarly with `before!`*
|
366
|
+
|
367
|
+
### Example 10 (Dirty Checking of Instance Variables Changes)
|
368
|
+
|
369
|
+
```ruby
|
370
|
+
class Foo
|
371
|
+
include SuperCallbacks
|
372
|
+
|
373
|
+
attr_accessor :bar, :baz
|
374
|
+
|
375
|
+
after :bar= do |arg|
|
376
|
+
puts 'original values of all instance attributes:'
|
377
|
+
puts instance_variables_before_change
|
378
|
+
|
379
|
+
puts 'original value:'
|
380
|
+
puts instance_variable_before_change :@bar
|
381
|
+
|
382
|
+
if instance_variable_changed? :@bar
|
383
|
+
puts 'new value'
|
384
|
+
@arg
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
foo = Foo.new
|
390
|
+
foo.bar = 1 # bar is changed from nil to 1
|
391
|
+
# => original values of all instance attributes:
|
392
|
+
# => {}
|
393
|
+
# => original value:
|
394
|
+
# => nil
|
395
|
+
# => new value:
|
396
|
+
# => 1
|
397
|
+
foo.bar = 1 # bar is not changed from 1 to 1
|
398
|
+
# => original values of all instance attributes:
|
399
|
+
# => { :@bar => 1 }
|
400
|
+
# => original value:
|
401
|
+
# => 1
|
402
|
+
```
|
403
|
+
|
404
|
+
*Notice above on the second time `foo.bar = 1` is called, "new value" was no longer "puts", because `@bar` didn't change from 1 to 1. You can only use `instance_variables_before_change`, instance_variable_before_change` and `instance_variable_changed?` inside the SuperCallback cycle; otherwise you will get a `"You cannot call this method outside the SuperCallback cycle"` error.
|
405
|
+
|
406
|
+
*Above uses `after!`, but works similarly with `before!`*
|
407
|
+
|
408
|
+
## TODOs
|
409
|
+
* when the need already arises, implement `around` (If you have ideas or want to help this part, please feel free to fork or send me a message! :)
|
410
|
+
* [Found a new bug I could not solve](https://github.com/jrpolidario/super_callbacks/issues/1). If you have any ideas how to solve this, please feel to submit a merge request! :) At the moment, this is not important to me (yet?) as I develop my game engine, so I'm leaving this here for now, and I'll come back again into this later.
|
411
|
+
|
412
|
+
## Development
|
413
|
+
|
414
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
415
|
+
|
416
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
417
|
+
|
418
|
+
## Contributing
|
419
|
+
|
420
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/jrpolidario/super_callbacks. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
421
|
+
|
422
|
+
## License
|
423
|
+
|
424
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
425
|
+
|
426
|
+
## Changelog
|
427
|
+
|
428
|
+
* 1.1.0 (2019-08-14)
|
429
|
+
* [Supported "dirty" checking of instance variable changes](#example-10-dirty-checking-of-instance-variables-changes)
|
430
|
+
* 1.0.3 (2019-08-12)
|
431
|
+
* Cleaner code without explicitly calling `run_callbacks` anymore; done now because of ruby upgrade from 1.9 to 2.0+ which already supports `prepend`
|
432
|
+
* Supported both class and instance level callbacks
|
433
|
+
* Supported inherited callbacks
|
434
|
+
* v0.2.1 (2019-08-09) *From `dragonruby_callbacks`*
|
435
|
+
* Fixed syntax errors for ruby 1.9.3; Fixed not supporting subclasses of Proc, String, or Symbol
|
436
|
+
* v0.2 (2019-08-08) *From `dragonruby_callbacks`*
|
437
|
+
* Supported [conditional callbacks](#conditional-callbacks) with `:if`
|
438
|
+
* v0.1 (2019-08-07) *From `dragonruby_callbacks`*
|
439
|
+
* Done all
|