Add Hook#each_callback and refactor execution to use it.
Add ability to clear callbacks from hooks.
Copy each_callback to a new null-parented set. Add ability to disconnect hooks from their parents
Replace writable access with #fetch_or_create_* Make #hooks and #callbacks read-only
A Listener is an object attached to a wildcard calback. Every event that passes through the callback is sent to the listener as a method call corresponding to the hook name. Add Listener API
Add an (easy) way to remove listeners
(Maybe) Verify that recursive handlers call either skip, next, or cancel.
Add #skip and #cancel methods to Event.
Consider using Roxy for #hooks and #callbacks extensions.
Standard, extensable method for deriving handles from objects
Driver: we need to be able to remove a listener using the the listener object as an index.
Reconsider fetch_or_create_* methods - they are kinda ugly.
More Hook parent/child unification
Most Hook methods should behave as if the hook contained all of its parent’s callbacks as well. Specifically:
- It should not be possible to add a callback with the same handle as an existing parent callback
- #callbacks should probably return a unified set of all callbacks
Collect return values when running hooks iteratively
Rewrite iterative model in terms of recursive
This will make some of the other TODOs possible/more feasible.
May want to push the execution models out into separate Event classes, e.g. IterativeEvent and RecursiveEvent. An IterativeEvent could apply itself to a callback generator in such a way that it collected return values into an array.
Write example “error strategy filter”
A possible implementation for turning exceptions into benign values:
Wrap callback execution in a begin…rescue block. If an exception is raised, catch it, and wrap it in a new exception which inludes a reference to the callback stack. An exception filter further up the chain can:
- Catch the wrapped exception
- Create a Failure object which references the exception
- Replace the top element of the callback stack with a stub that just returns the Failure object.
- Retry the exception.
Syntax sugar for before_ and after_ filters
class ZeroWing define_hook :we_get_signal
before_we_get_signal :foo after_we_get_signal :bar end
Syntax sugar for execute_hook
execute_we_get_signal(arg1, arg2) run_we_get_signal(arg1, arg2)
Interleave wildcard callback execution based definition order
Instead of running all wildcards first or last.
One possible approach is to combine wildcards and specific callbacks into a single set before executing. This would require reworking how we generate indices, if nothing else. Indices would have to be unique across the whole class.
Another approach: when adding a wildcard callback, first add it individually to every existing hook. Then add it to a class-wide “wildcard list”. When a new hook is defined, add all the wildcards in the wildcard list to it.
A side-effect of the second approach is that it would be possible to remove wildcard callbacks from individual instances/hooks using remove_callback(). This may be a feature.
Make it possible to add a Listener at the class level
Both internally and externally to the class
Make callback macros accept listeners
Add ability for listeners to see event object
Currently only the event arguments are passed.
May want to make the core Listener API a single #notify(event) call, and then have SomeClass::Listener add the demultiplexing code.