Observer Decoration¶
In this reversed decoration scheme, the observer decorator collects its
observables. This seems more elaborate at first glance, but some prefer to
explicitly designate the Observer
and Observable
roles in their code.
Because an observer decoration uses observable methods, all observable(s) must always be declared and decorated before their observer(s).
1. Rule: Declare Observables before Observers
2. Rule: Decorating as @Observable before using in an @Observer
The initial example Case 1
from Pyc. 37 in
Observable Decoration
translates to:
from decoratory.observer import Observer, Observable
from decoratory.basic import X
@Observable # 2. Rule: decorate dog before usage!
def dog(act: str = "Woof!"): # 1. Rule: declare dog before person!
print(f"{dog.__name__} acts '{act}'")
@Observer(observables=X(dog, 'Hey, dog!'))
def person(say: str = "Hello?"):
print(f"{person.__name__} says '{say}'")
# Case 1: Observer decoration
# ---> Person as an observer to observable dog
person() # person says 'Hello?' (person acting)
dog() # dog acts 'Woof!' (dog acting)
# person says 'Hey, dog!'(observer to dog)
The use of the semantic cross-function X
from decoratory.basic
instead of F
indicates that dog
is the observable, but the X
arguments apply for the observer person
.
For multiple decorations, the order of decoration is also relevant here.
The situation Case 2
from Pyc. 38 in
Observable Decoration
with person, dog and cat would then look like:
@Observable # 2. Rule: dog before cat & person
def dog(act: str = "Woof!"): # 1. Rule: dog before cat & person
print(f"{dog.__name__} acts '{act}'")
@Observer(observables=X(dog, 'Roar!'))
@Observable # 2. Rule: observable cat before person
def cat(act: str = "Meow!"): # 1. Rule: cat before person
print(f"{cat.__name__} acts '{act}'")
@Observer(observables=[X(dog, 'Hey, dog!'),
X(cat.substitute.callee, say='Hey, cat!')])
def person(say: str = "Hello?"):
print(f"{person.__name__} says '{say}'")
# Case 2: Stacked observer decoration
# ---> Cat observes dog, person observes cat and dog
person() # person says 'Hello?' (person acting)
cat() # cat acts 'Meow!' (cat acting)
# person says 'Hey, cat!'(observer to cat)
dog() # dog acts 'Woof!' (dog acting)
# cat acts 'Roar!' (observer to dog)
# person says 'Hey, cat!'(observer to cat)
# person says 'Hey, dog!'(observer to dog)
Here, cat becomes an observer but its callee cat.substitute.callee
is an
observable which can be observed by person! This observed cat observes
the dog, reacts and triggers the person.
To reproduce also Case 4
from Pyc. 40 in
Observable Decoration
above, simply swap the order of the decorations at the cat and the person then
looks directly at the observed cat.
@Observable # 2. Rule: dog before cat & person
def dog(act: str = "Woof!"): # 1. Rule: dog before cat & person
print(f"{dog.__name__} acts '{act}'")
@Observable # 2. Rule: cat before person
@Observer(observables=X(dog, 'Roar!'))
def cat(act: str = "Meow!"): # 1. Rule: cat before person
print(f"{cat.__name__} acts '{act}'")
@Observer(observables=[X(dog, 'Hey, dog!'), X(cat, say='Hey, cat!')])
def person(say: str = "Hello?"):
print(f"{person.__name__} says '{say}'")
# Case 3: Stacked observer decoration
# ---> Cat observes dog, person observes cat and dog
person() # person says 'Hello?' (person acting)
cat() # cat acts 'Meow!' (cat acting)
# person says 'Hey, cat!'(observer to cat)
dog() # dog acts 'Woof!' (dog acting)
# cat acts 'Roar!' (observer to dog)
# person says 'Hey, dog!'(observer to dog)
Now, both dog and cat end up being observables, observed by the person. But the
cat observing the dog is the original cat, which does not inform the person
of its activities, and so person’s statement Hey, cat!
is missing.
© Copyright 2020-, Martin Abel, eVation. All Rights Reserved. |