AW: [mailinglist] [Python-de] Funktion sucht Aufrufer

Diez B. Roggisch deets at web.de
Fre Sep 10 17:18:19 CEST 2004


Hallo,
> gerne genommes konstrukt zb. in aspekt orientierten sprachen
> (cflow | cflowbelow). warum? eine program laeuft im testmodus
> und deine funktion "getFoo(): return Foo()" moechte in dem
> falle lieber ein neues TestFoo() zurueckgeben (protokoll
> gleich zu Foo).
> die einzige moeglichkeit das anders hinzubekommen waere das
> objekt, dass getFoo besitzt mit dem wissen ueber den "testzustand"
> zu versehen. das kann auf zwei arten passieren per membervariable
> oder als uebergabe variablen durch alle func/methoden aufrufe.

Ich sehe da noch globale Variablen oder Factories, oder auch sehr nett: 
konditionale imports.

> beide optionen moegen nicht immer zur verfuegung stehen. wenn objekte
> zb. durch faktories erzeugt werden und es keine moeglichkt gibt
> den zustand zu setzen. moeglichkeit zwei ist zudem enorm fragil.

Gerade da geht das doch sehr gut: Der ganze Sinn einer Factory liegt doch eben 
genau darin, eine protokollinvariante Implementation zu liefern - wenn das 
nicht so waere, koennte man ja gleich eine konkrete Implementatiton liefern.

> def getFoo():
>     if (suche_stack_nach_aufrufenden_testtreiber()):
>        return TestFoo()
>     else:
>        return Foo()

Also letztlich ist das ja nix anderes als eine Factory - und halt 
parametisiert ueber den Stack. Auf die Idee bin ich noch nicht gekommen, aber 
als ueberlegen kann ich das auch nicht wirklich empfinden. Man muss ja 
jeweils gleich viel wissen - entweder eine Variable abfragen, oder wissen wie 
der Stack auszusehen hat.

> wesentlich besser. noch angenehmer jedoch waere ein verheiraten mit
> descriptoren (2.4)
>
> <code achtung="unvollstaendig_nur_zur_demo">
> def test_advise(Type):
>     #wrap original funtion into delegate
>     if (suche_stack_nach_aufrufenden_testtreiber()):
>        return TestFoo()
>     else:
>        return delegate()
>
> # und dann hier
> @test_advise(TestFoo)
> def getFoo():
>        return Foo()
> </code>
>
> nicht nur, dass du in dem fall die testzustand nicht setzen musst,
> dein eigentlicher code bleibt vom wissen um das testen voellig
> unberuehrt und wartbar. ist doch nett.

Wo ist da jetzt der Gewinn? Ich bin ja auch gespannt auf Dekoratoren, aber das 
hier aendert nix - gleicher code, und eine Deklaration vor getFoo - wenn man 
nicht weiss, was die wirklich tut, dann ist mir die obrige Variante lieber, 
denn dann sehe ich direkt was wann passiert.

Du hast ja selber schon die aspekt-orientierung erwaehnt - ich halte das 
durchaus auch fuer eine nette Idee, IMHO aber nur dann sinnvoll wenn die 
Aspekte hinreichend unabhaengig sind. Beispiele sind zB tracking/logging, 
Transaktionsmanagement, authentifiziernung/authorisierung, boxing/unboxing. 

In dem Moment  aber wo ein Aspekt soviel wissen muss ueber interna des Codes 
an den er gebunden wird, sorgt er nur fuer unueberschtlichkeit - dann lieber 
alles an einem Platz.

Aber das ist nat. alles Ansichtsache, und die Idee scheint zumindest nicht 
kraenker als andere :)

MfG Diez