Update docs
This commit is contained in:
parent
afb1a7996f
commit
689ab9a3ef
@ -3,7 +3,7 @@ Event system
|
||||
|
||||
Generic library provides ``generic.event`` module which helps you implement
|
||||
event systems in your application. By event system I mean an API for
|
||||
*subscribing* for some types of events and to *fire* those events so previously
|
||||
*subscribing* for some types of events and to *handle* those events so previously
|
||||
subscribed *handlers* are being executed.
|
||||
|
||||
.. contents::
|
||||
@ -23,18 +23,18 @@ events' types, so it's natural to model those as classes::
|
||||
|
||||
Now you want to register handler for your event type::
|
||||
|
||||
from generic.event import subscriber
|
||||
from generic.event import Manager
|
||||
|
||||
@subscriber(CommentAdded)
|
||||
manager = Manager()
|
||||
|
||||
@manager.subscriber(CommentAdded)
|
||||
def print_comment(ev):
|
||||
print "Got new comment: %s" % ev.comment
|
||||
|
||||
Then you just call ``generic.event.fire`` function with ``CommentAdded``
|
||||
Then you just call ``generic.event.handle`` function with ``CommentAdded``
|
||||
instance as its argument::
|
||||
|
||||
from generic.event import fire
|
||||
|
||||
fire(CommentAdded(167, "Hello!")) # prints `Got new comment: Hello!`
|
||||
manager.handle(CommentAdded(167, "Hello!")) # prints `Got new comment: Hello!`
|
||||
|
||||
This is how it works.
|
||||
|
||||
@ -48,12 +48,12 @@ API reference
|
||||
-------------
|
||||
|
||||
.. autoclass:: generic.event.Manager
|
||||
:members: subscribe, subscriber, fire, unsubscribe
|
||||
:members: subscribe, subscriber, handle, unsubscribe
|
||||
|
||||
Functions below are just aliases for methods of globally instantiated
|
||||
manager:
|
||||
|
||||
.. autofunction:: generic.event.subscribe(handler, event_type)
|
||||
.. autofunction:: generic.event.subscriber(event_type)
|
||||
.. autofunction:: generic.event.fire(event)
|
||||
.. autofunction:: generic.event.handle(event)
|
||||
.. autofunction:: generic.event.unsubscribe(handler, event_type)
|
||||
|
@ -29,7 +29,7 @@ or *pip* command::
|
||||
In case you find a bug or have a feature request, please file a ticket at
|
||||
`GitHub Issues`_.
|
||||
|
||||
.. _GitHub Issues: https://github.com/andreypopp/generic/issues
|
||||
.. _GitHub Issues: https://github.com/gaphor/generic/issues
|
||||
|
||||
Development process
|
||||
-------------------
|
||||
@ -37,9 +37,9 @@ Development process
|
||||
Development takes place at `GitHub`_, you can clone source code repository with the
|
||||
following command::
|
||||
|
||||
% git clone git://github.com/andreypopp/generic.git
|
||||
% git clone git://github.com/gaphor/generic.git
|
||||
|
||||
In case submitting patch or GitHub pull request please ensure you have
|
||||
corresponding tests for your bugfix or new functionality.
|
||||
|
||||
.. _GitHub: https://github.com/andreypopp/generic
|
||||
.. _GitHub: https://github.com/gaphor/generic
|
||||
|
@ -16,17 +16,17 @@ Multifunctions
|
||||
|
||||
Suppose we want to define a function which behaves differently based on
|
||||
arguments' types. The naive solution is to inspect argument types with
|
||||
``isinstance`` function calls but generic provides us with ``@multifunction``
|
||||
``isinstance`` function calls but generic provides us with ``@multidispatch``
|
||||
decorator which can easily reduce the amount of boilerplate and provide
|
||||
desired level of extensibility::
|
||||
|
||||
from generic.multidispatching import multifunction
|
||||
from generic.multidispatch import multidispatch
|
||||
|
||||
@multifunction(Dog)
|
||||
@multidispatch(Dog)
|
||||
def sound(o):
|
||||
print "Woof!"
|
||||
|
||||
@sound.when(Cat)
|
||||
@sound.register(Cat)
|
||||
def sound(o):
|
||||
print "Meow!"
|
||||
|
||||
@ -49,7 +49,7 @@ even in separate module::
|
||||
|
||||
from somemodule import sound
|
||||
|
||||
@sound.when
|
||||
@sound.register
|
||||
def sound(o)
|
||||
print "Quack!"
|
||||
|
||||
@ -63,23 +63,23 @@ You can also define multifunctions of several arguments and even decide on which
|
||||
of first arguments you want to dispatch. For example the following function will
|
||||
only dispatch on its first argument while requiring both of them::
|
||||
|
||||
@multifunction(Dog)
|
||||
@multidispatch(Dog)
|
||||
def walk(dog, meters):
|
||||
print "Dog walks for %d meters" % meters
|
||||
|
||||
But sometimes you want multifunctions to dispatch on more than one argument,
|
||||
then you just have to provide several arguments to ``multifunction`` decorator
|
||||
then you just have to provide several arguments to ``multidispatch`` decorator
|
||||
and to subsequent ``when`` decorators::
|
||||
|
||||
@multifunction(Dog, Cat)
|
||||
@multidispatch(Dog, Cat)
|
||||
def chases(dog, cat):
|
||||
return True
|
||||
|
||||
@chases.when(Dog, Dog)
|
||||
@chases.register(Dog, Dog)
|
||||
def chases(dog, dog):
|
||||
return None
|
||||
|
||||
@chases.when(Cat, Dog)
|
||||
@chases.register(Cat, Dog)
|
||||
def chases(cat, dog):
|
||||
return False
|
||||
|
||||
@ -104,17 +104,17 @@ never fall with ``TypeError`` anymore.
|
||||
Multimethods
|
||||
------------
|
||||
|
||||
Another functionality provided by ``generic.multidispatch`` module are
|
||||
Another functionality provided by ``generic.multimethod`` module are
|
||||
*multimethods*. Multimethods are similar to multifunctions except they are...
|
||||
methods. Technically the main and the only difference between multifunctions and
|
||||
multimethods is the latter is also dispatch on ``self`` argument.
|
||||
|
||||
Implementing multimethods is similar to implementing multifunctions, you just
|
||||
have to decorate your methods with ``multimethod`` decorator instead of
|
||||
``multifunction``. But there's some issue with how Python's classes works which
|
||||
``multidispatch``. But there's some issue with how Python's classes works which
|
||||
forces us to use also ``has_multimethods`` class decorator::
|
||||
|
||||
from generic.multidispatch import multimethod, has_multimethods
|
||||
from generic.multimethod import multimethod, has_multimethods
|
||||
|
||||
@has_multimethods
|
||||
class Animal(object):
|
||||
@ -123,7 +123,7 @@ forces us to use also ``has_multimethods`` class decorator::
|
||||
def can_eat(self, food):
|
||||
return True
|
||||
|
||||
@can_eat.when(Meat)
|
||||
@can_eat.register(Meat)
|
||||
def can_eat(self, food):
|
||||
return False
|
||||
|
||||
@ -143,7 +143,7 @@ and override ``can_eat`` method definition::
|
||||
@has_multimethods
|
||||
class Predator(Animal):
|
||||
|
||||
@Animal.can_eat.when(Meat)
|
||||
@Animal.can_eat.register(Meat)
|
||||
def can_eat(self, food):
|
||||
return True
|
||||
|
||||
@ -166,14 +166,14 @@ decorator just like in example for multifunctions.
|
||||
API reference
|
||||
-------------
|
||||
|
||||
.. autofunction:: generic.multidispatch.multifunction
|
||||
.. autofunction:: generic.multidispatch.multidispatch
|
||||
|
||||
.. autofunction:: generic.multidispatch.multimethod
|
||||
.. autofunction:: generic.multimethod.multimethod
|
||||
|
||||
.. autofunction:: generic.multidispatch.has_multimethods
|
||||
.. autofunction:: generic.multimethod.has_multimethods
|
||||
|
||||
.. autoclass:: generic.multidispatch.FunctionDispatcher
|
||||
:members: when, override, otherwise
|
||||
:members: register
|
||||
|
||||
.. autoclass:: generic.multidispatch.MethodDispatcher
|
||||
:members: when, override, otherwise
|
||||
.. autoclass:: generic.multidmultimethodispatch.MethodDispatcher
|
||||
:members: register, otherwise
|
||||
|
Loading…
x
Reference in New Issue
Block a user