+
+def in_callback(self, *args, **kwargs):
+ """Enable callbacks inside methods.
+
+ Sometimes :func:`callback` isn't granular enough. This function
+ can accomplish the same thing from inside your method, giving you
+ control over the arguments passed and the time at which the call
+ is made. It draws from the same `._callbacks` dictionary.
+
+ Examples
+ --------
+
+ Callbacks are called with the class instance, method instance, and
+ returned arguments of the method they're attached to.
+
+ >>> def c(self, method, *args, **kwargs):
+ ... print '\\n '.join([
+ ... 'callback:',
+ ... 'class: %s' % self,
+ ... 'method: %s' % method,
+ ... 'args: %s' % (args,),
+ ... 'kwargs: %s' % kwargs])
+
+ Now place `in_callback` calls inside any interesting methods.
+
+ >>> class X (object):
+ ... def __init__(self):
+ ... self._callbacks = {'xyz': c}
+ ...
+ ... def xyz(self):
+ ... "xyz's docstring"
+ ... print 'usual xyz business'
+ ... in_callback(self, 5, my_kw=17)
+ ... return (0, 1, 1, 2, 3, 5)
+ ...
+ ... def abc(self):
+ ... "abc's docstring"
+ ... in_callback(self, p1=3.14, p2=159)
+ ... print 'usual abc business'
+ ...
+ >>> x = X()
+
+ Here's our callback in `xyz`.
+
+ >>> r = x.xyz() # doctest: +ELLIPSIS
+ usual xyz business
+ callback:
+ class: <hooke.util.callback.X object at 0x...>
+ method: <bound method X.xyz of <hooke.util.callback.X object at 0x...>>
+ args: (5,)
+ kwargs: {'my_kw': 17}
+ >>> r
+ (0, 1, 1, 2, 3, 5)
+
+ Note that we haven't attached a callback to `abc`.
+
+ >>> r = x.abc()
+ usual abc business
+
+ Now we attach the callback to `abc`.
+
+ >>> x._callbacks['abc'] = c
+ >>> r = x.abc() # doctest: +ELLIPSIS
+ callback:
+ class: <hooke.util.callback.X object at 0x...>
+ method: <bound method X.abc of <hooke.util.callback.X object at 0x...>>
+ args: ()
+ kwargs: {'p2': 159, 'p1': 3.1400000000000001}
+ usual abc business
+
+ You can also place an iterable in the `_callbacks` dict to run an
+ array of callbacks in series.
+
+ >>> def d(self, method, *args, **kwargs):
+ ... print 'callback d'
+ >>> x._callbacks['abc'] = [d, c, d]
+ >>> r = x.abc() # doctest: +ELLIPSIS
+ callback d
+ callback:
+ class: <hooke.util.callback.X object at 0x...>
+ method: <bound method X.abc of <hooke.util.callback.X object at 0x...>>
+ args: ()
+ kwargs: {'p2': 159, 'p1': 3.14...}
+ callback d
+ usual abc business
+ """
+ method_name = caller_name(depth=2)
+ callback = self._callbacks.get(method_name, None)
+ nm = getattr(self, method_name)
+ if is_iterable(callback):
+ for cb in callback:
+ cb(self, nm, *args, **kwargs)
+ elif callback != None:
+ callback(self, nm, *args, **kwargs)