Closed selfsame closed 9 years ago
Some experiments with decoraters turned out well. The decorators register functions based on their lifecycle decorator, verb, arity, and argument types.
@before
@given(human, animal)
def interact(a, b):
print name(a), "pets the", name(b)
is converted to a tree:
{"interact": #string verb function name
{2: #arity
{"before": #lifecycle
#a tuple of predicate fns must return true when applied to the args
(<fn human>, <fn animal>) :
<fn interact> #the original function we had decorated
}}}}
The data for each function is merged into the registry with ordered dicts.
When a verb function is invoked, it pulls all relevant entries for it's verb, arity, etc., which it calls in order of lifecycle (only one fn per lifecycle will be called).
The predicate type dispatch is pretty fun, predicate functions are easy to compose
def a(*args):
def f(e):
if not isinstance(e, dict): return False
for spec in args:
if string(spec):
if spec not in e: return False
elif function(spec):
if not spec(e): return False
else: return False
return True
return f
def isnot(posf):
def negf(x):
return not posf(x)
return negf
human = a('human')
animal = a('entity', isnot(human))
object = isnot( a('entity'))
elder = a(human, 'male', old)
@after
@given(elder, a('room'))
def enter(e, b):
print name(a), "hobbles into", name(b)
Totally composable and described here https://github.com/selfsame/mud.tilde.town/wiki/actions
component.action functions are lacking some important compositions:
overriding, where an action handler can prevent earlier handlers from firing.
before/after/check co-functions, maybe python decorators can provide this?