Remove docs on multidispatch since separated back to generic library
Signed-off-by: Dan Yeaw <dan@yeaw.me>
This commit is contained in:
parent
c41f7d7fb5
commit
5d44707667
@ -45,7 +45,6 @@ Tech section
|
||||
undo
|
||||
xml-format
|
||||
event_system
|
||||
multidispatching
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
@ -1,94 +0,0 @@
|
||||
# Multi-Dispatching
|
||||
|
||||
Multidispatching allows Gaphor to define methods and functions which should
|
||||
behave differently based on the argument types without cluttering
|
||||
`if-elif-else` chains and `isinstance` calls.
|
||||
|
||||
All you need is inside `gaphor.utils.generic.multidispatch` module. See examples
|
||||
below to learn how to use it to define multifunctions and multimethods.
|
||||
|
||||
## Multifunctions
|
||||
|
||||
Suppose we want to define a function which behaves differently based on
|
||||
arguments' types. One solution may be to inspect argument types with
|
||||
`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 gaphor.utils.generic.multidispatching import multidispatch
|
||||
|
||||
@multidispatch(Dog)
|
||||
def sound(o):
|
||||
print("Woof!")
|
||||
|
||||
@sound.when(Cat)
|
||||
def sound(o):
|
||||
print("Meow!")
|
||||
|
||||
Each separate definition of `sound` function works for different
|
||||
argument types, we will call each such definition *a multidispatch case*
|
||||
or simply *a case*. We can test if our `sound` multidispatch works as
|
||||
expected:
|
||||
|
||||
>>> sound(Dog())
|
||||
Woof!
|
||||
>>> sound(Cat())
|
||||
Meow!
|
||||
>>> sound(Duck())
|
||||
Traceback
|
||||
...
|
||||
TypeError
|
||||
|
||||
The main advantage of using multifunctions over single function with a
|
||||
bunch of `isinstance` checks is extensibility \-- you can add more cases
|
||||
for other types even in separate module:
|
||||
|
||||
from somemodule import sound
|
||||
|
||||
@sound.when
|
||||
def sound(o)
|
||||
print("Quack!")
|
||||
|
||||
When behaviour of multidispatch depends on some argument we will say
|
||||
that this multidispatch *dispatches* on this argument.
|
||||
|
||||
## Multifunctions of Several Arguments
|
||||
|
||||
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:
|
||||
|
||||
@multidispatch(Dog)
|
||||
def walk(dog, meters):
|
||||
print(f"Dog walks for {meters} meters")
|
||||
|
||||
But sometimes you want multifunctions to dispatch on more than one
|
||||
argument, then you just have to provide several arguments to
|
||||
`multidispatch` decorator and to subsequent `when` decorators:
|
||||
|
||||
@multidispatch(Dog, Cat)
|
||||
def chases(dog, cat):
|
||||
return True
|
||||
|
||||
@chases.when(Dog, Dog)
|
||||
def chases(dog, dog):
|
||||
return None
|
||||
|
||||
@chases.when(Cat, Dog)
|
||||
def chases(cat, dog):
|
||||
return False
|
||||
|
||||
You can have any number of arguments to dispatch on but they should be
|
||||
all positional, keyword arguments are allowed for multifunctions only if
|
||||
they're not used for dispatch.
|
||||
|
||||
## API reference
|
||||
|
||||
```eval_rst
|
||||
.. autoclass:: gaphor.misc.generic.multidispatch.multidispatch
|
||||
```
|
||||
|
||||
```eval_rst
|
||||
.. autoclass:: gaphor.misc.generic.multidispatch.FunctionDispatcher
|
||||
```
|
Loading…
x
Reference in New Issue
Block a user