→ Callbacks
Get Version
0.0.2Callbacks?
You know! That nifty feature that's also in Rails. First let me explain what callbacks are: callbacks are pieces of code that get called whenever a predefined action occurs.
A simple example: when a song in your favourite music player has ended a callback could be issued which will update the UI, jump to the next song and update your last.fm account.
This is of course a very simple example (I don't know how music players work). But it could well work just like I described.
Usage
But if you found this little gem, you of course now what callbacks are. So lets jump to the nice stuff: code examples!
1 require 'callbacks' 2 3 Object.send(:include, Callbacks) 4 Object.add_callback_methods :inspect 5 Object.before_inspect do 6 print "Going to inspect #{self.class}\n" 7 end 8 9 o = Object.new 10 o.inspect #will print "Going to inspect Object"
Another (better example)
1 class MusicPlayer 2 3 def play 4 p 'begining to play song' 5 sleep 5 6 self.end_of_song 7 end 8 9 def end_of_song 10 p 'End reached. Quiting player' 11 end 12 13 include Callbacks 14 add_callback_methods :end_of_song 15 16 before_end_of_song do 17 p "I'm almost gonna die. I feel the end coming." 18 end 19 20 after_end_of_song do 21 p 'Arghhh...' 22 end 23 end 24 25 mp = MusicPlayer.new 26 mp.play
How is this magic achieved?
First of all: when you include the Callbacks module in a class, several class methods get added. For example:
- add_callback_methods
- callback_methods
- callback_actions
- et cetera
An instance variable called @callback_methods and one called @callback_actions are now available in the class where you included Callbacks.
When you add a callback with add_callback_methods(), @callback_methods gets filled.
A couple of more methods are generated:
- before_#{method}
- after_#{method}
- #{method}_without_callbacks
Now we can add actions to the class with the usage of (for example) after_boot & before_boot
With these two methods the instance variable @callback_actions is filled.
Callbacks are stored as a callback object in this variable. The object saves the original input containing one of these:
- String
- Proc
- Block
- Symbol
The very first time a callback is called, a proc (or block. Depending on the need to access "self" of the class used for the callbacks) is generated and stored in the callback object.
More documentation
More documentation can be found here.
Problems
When you do something like:
1 require 'callbacks' 2 class Tester 3 include Callbacks 4 add_callback_methods :exit 5 6 def exit 7 end 8 end 9 10 Tester.before_exit do 11 p 'exiting' 12 end 13 t = Tester.new 14 t.exit
This won't work! Why? Because the add_callback_methods method is
called before the actual method itself exists. So when the method "exit" is defined,
it overwrites the magically created method.
If anyone knows a good solution for this problem, please contact me! No, really!
Future
In version 0.2 I want to add stuff so you can add callbacks to this one instance of a class and not ALL instances. If you have interesting suggestions: mail me!
And I think about adding some method aliases like add_hook or add_handler and stuff like that.
And what about another syntax? Like this
1 class Tester 2 include Callbacks 3 4 add_callback :exit do 5 before_exit do 6 p 'Going to exit' 7 end 8 9 after_exit :do_something_wicked 10 end 11 12 #this won't work anymore then 13 add_callback_methods :exit 14 after_exit :do_something_wicked 15 end
What do ya think? Keep the old syntax? Or use a new more dsl-like syntax? Please let me know!!!
Theme extended from Paul Battley
This website was created with Webby