[linux-l] API-Doc vs. Literate Programming (war: Warum gibt es keine einheitliche Dokumentation?)

Steffen Dettmer steffen at dett.de
Di Jan 2 18:40:33 CET 2007


* Volker Grabsch wrote on Tue, Jan 02, 2007 at 01:35 +0100:
> On Mon, Jan 01, 2007 at 09:03:32PM +0100, Steffen Dettmer wrote:
> > Der Vorteil wäre, dass man einfach verlinken kann.
> 
> Will sagen: Ganz oder gar nicht.
> 
> > Doch, wenn ich ein Projekt in drei Sprachen implementieren, ziehe ich
> > vor, wenn die Doku in einem Format kommt. Warum soll eine Erklärung für
> > eine Python-Funktion unbedingt anders aussehen, als eine für Java?
> 
> Warum sollte der Python-Teil des Projektes für Python-Programmierer
> ungewohnt dokumentiert sein, oder der Java-Teil für Java-Programmierer
> ungewohnt? Das könnte man genauso fragen.
> 
> Natürlich wiegen diese Fragen nicht so schwer wie z.B. bei einem reinen
> Python oder reinen Java-Projekt, da stimme ich dir zu.

Wenn es jetzt schlecht ist (weil nicht einheitlich etc) und man es
verbessern möchte, wird es natürlich anders. Das dieses andere ungewohnt
ist, ist dabei natürlich klar (weil man ja das Schlechte gewohnt ist).

Ich glaub, Java ist ein Parade-Beispiel für "Gewohnheiten". Ich habe
z.B. mal versucht rauszukriegen, warum in Java Exceptions
IrgendwasException heissen. Eine Konvention. Gilt nur genau für
Exceptions, nicht für Errors oder andere Klassen. Nennt man einen "int"
"myInt" oder eine Klasse (mit allen Basisklassen) CatAnimalObject oder
so, werden wohl die meisten zustimmen, dass das dämlich ist. Wer
dähmlich ist h schreibt, ist nähmlich dähmlich - oder wie war das? lol. 
Gerade in Java, wo man auf Grund einer weiteren Sprachbeschränkung ja eh
nur Exceptions (...) werfen kann, so dass gerade Exception keinen
Mehrwert bietet. Der einzigen Grund, den ich hörte, war, dass JavaDoc
Exceptions mit in die Klassenliste aufnimmt. Damit man gleich sähe, was
Exceptions sind. Super Argument. Na ja.

Also, Ende der Ausuferung. Was ich sagen wollte: Es gibt auch schlechte
Gewohnheiten.

> > > Das heißt, schreibe *eine* Doku, die beide APIs erklärt, und ggf. auf
> > > Unterschiede hinweist. [...] Aus diesem gemeinsamen Dokument (das auch
> > > aus mehreren Dateien bestehen kann) generierst du dann C++ und
> > > Java-Dateien, die du dann in den Compiler jagst.
> > 
> > Das klingt unrealistisch aufwändig...
> 
> Das ist es nicht unbedingt. Man muss es halt probieren. Das erstmal
> aufzusetzen ist vielleicht haarig, aber letztendlich geht es z.B., indem
> du die Doku in LaTeX schreibst und entsprechende Kommentare an die
> Code-Schnipsel setzt.
> 
> Ein Script, das diese Kommentare rausholt und für Compiler aufbereitet
> 
> Die Beispiel-Codes direkt als Testprogramme zu nehmen, das ist auch noch
> vertretbarer Aufwand, zumal es z.B. für Python sowas schon fertig gibt
> (doctest). Das erhöht auch wieder die Qualität und spart auf Dauer
> Arbeit.
> 
> Sowas für ein konkretes Projekt aufzusetzen, sodass es wirklich nur
> das leistet was man braucht, müsste in ein paar Arbeitstagen zu schaffen
> sein, bei einem größeren Projekt also Peanuts.

Halte ich für unrealistisch. Das sind 20.000 - 30.000 Zeilen C++ im
grössten Modul und vielleicht die Hälfte Java. Da ist nix mit in ein
paar Arbeitstage in LaTeX umschreiben. Was IMHO sowieos unwartbar werden
würde. Aber ist vielleicht nur eine (meine) schlechte Gewohnheit ;)

> Die Compilerausgabe kann man dann auch noch manupulieren, sodass Tools
> wie Eclipse oder Vim nicht zur Zeile 1354 in "myprog.java", sondern zur
> Zeiel  1354 in "myprog.tex" springen. Auch das kann man im Makefile
> zentral in wenigen Zeilen regeln.

(Ja, das geht, bis man automake oder ant nimmt... Man kann aber einen
compiler oder besser make wrapper nehmen)

> Java will eine Datei pro Klasse haben, das ist kann es ja ruhig. 

Ja, das ist auch so ein Bug, der als Feature verkauft wird. Die Jungs
haben Codegenerierung wohl einfach vergessen. Na ja, vielleicht wird
Java irgendwann erwachsen und kann dann auch sowas, aber ich glaub da
eher nicht dran.

> Dieser einmalige Aufwand sollte bei großen Projekten die eingesparte
> Redundanz locker wett machen. 

Einmalige Aufwand? Es wird alles aufwändiger, auch debuggen und so weil
sourcen komisch. Änderungen können "Externe" kaum machen, weil man da ja
was ganz anderes machen will (Gewohnheit ;)).

Redundanz darf man auch nicht überbewerten. Der "Pragmatische
Programmierer" sagt glaube ich: wenn Du Dich wiederholst, merke es Dir
und schreibe es ran.  Wenn Du Dich nochmal überholst, schreibe es gross
ran. Wenn Du Dich zum dritten Mal wiederholst, schreibs um. Oder sowas
in der Art.

Wenn sich die Doku nicht gerade ständig ändert, kann man das z.B. von
Studenten alles zusammen copy&pasten lassen. Vermutlich viel besser, als
eine "eigene Sprache" zu machen :)

> Und die vielen Fehler in der Doku, denen man vorbeugt! 

Kannst Du mir mal bitte drei bis zehn nennen?!

> Vorallem ist auch die Motivation viel höher, etwas besser zu
> dokumentieren, wenn die Doku nicht so weit vom Quelltext entfernt ist.

Das ist ein Argument für JavaDoc/Doxygen, nicht für irgendwas-LaTeX,
finde ich.

(obwohl hier die Gefahr ist, dass man denken könnte, solche low level
doku wäre hinreichend)

> Nein, den *eigentlichen* Aufwand sehe ich eher in der Umgewöhnung.
> Muss man ein Team davon erst einmal großartig überzeugen, hat man
> verloren.  Es gibt vielleicht sogar (firmen-)politische Widerstände.
> In einem kleinen, enthusiastischen Team sollte das aber möglich sein.

Na ja, es müsste erstmal "bewiesen" sein, dass es funktioniert. Man
kann keine 50K LOC auf LaTeX umstellen und Wochen später feststellen,
dass die Idee praktikabel ist (was ich aus dem Bauch herraus rate).

Alles nicht so einfach.

> > > Unterschiedliche Detail-Level. 
> > 
> > Nein, eben nicht!
> > 
> > Ziel der Benutzer-Dokumentation ist, interna nicht zu dokumentieren,
> > weil der Benutzer das nicht wissen soll, damit er sich nicht drauf
> > verlassen kann.
> > 
> > Für Libentwickler müssen natürlich genau die interna dokumentiert werden
> > - dafür interessieren ihn Beispielprogramme und update-Hinweise
> > vielleicht nicht.
> 
> Ich verstehe den Zusammenhang nicht. Zuerst sagst du, es sind nicht nur
> unterschiedliche Detail-Level. Danach sagst du, dass bestimmte Bereiche
> nur in die Benutzer-Doku kommen und andere nur in die Entwickler-Doku.
> Entspricht das nicht gerade dem Ein- und Ausblenden von Details?

Na gut, wenn ich eine Doku als \useronly und die andere als \devonly
zufällig in einer Datei habe und dann noch als Detaillevel bezeichne
(obwohl es vielleicht nicht eine Zeile gibt, die in beiden ist,
Reihenfolgen anders sind etc), dann entspricht das natürlich dem Ein-
und Ausblenden von Details? Aber nur technisch, nicht "logisch". Logisch
sind es zwei Dokumentationen.

> Natürlich ist das nur spekulativ, da ich hier kaum praktische
> Erfahrung vorweisen kann. Deshalb würde mich sehr interessieren, ob
> das hier wirklich nicht reicht, um zwei verschiedene API-Docs zu
> erzeugen, und wo man Denkfehler liegt (d.h. welche Details ich
> eventuell zu stark vereinfacht habe).

Na ja, ich kann mir nicht vorstellen, wie man das in LaTeX machen wollen
würde. Man muss ja die Prototypen etc dann dort schreiben, damit
irgendwas prüfen kann, ob das Sinn macht und es muss zusammen stehen,
weil man es ja dokumentiert. Doxygen versteht ja C++ Syntax. Muss ja,
damit er weiss, was ein Parameter ist etc. Wie soll sowas alles mit
LaTeX gehen? Klar, man kann sich als eigene LaTeX, WML oder sonstwie
basierte Sprache was ausdenken, was dann Java und C++ Code erzeugt. Da
kann man auch M4 nehmen oder so. Nee, WML wäre schon gut, glaub ich.
Aber was bringt das? Ich mein, es muss ja leichter wartbar werden - und
das kann ich mir beim besten Willen nicht vorstellen. Ich hab da schon
mal drüber nachgedacht, aber mir ist leider auch nix eingefallen.

Daher befürchte ich halt, dass das Problem gar nicht elegant lösbar
ist...

> > > Das ist ja nun wirklich das geringste Problem. Im
> > > Literate-Programming-Ansatz aber automatisch mit enthalten.  Dann
> > > generierst du eben nicht eine Doku und das C++/Java-Zeugs, sondern 2
> > > Dokus und das C++/Java-Zeugs. :-)
> > 
> > Ja klar, wenn man was generieren kann, geht sowas sicherlich. Vielleicht
> > hat man noch unterschiedliche Sprachen etc.
> 
> Gerade bei unterschiedlichen Sprachen möchte man die Übersetzungen
> einzelner Absätze doch beisammen halten, um zu verhindern, dass sie
> auseinander driften, oder?

Ja klar, wenn das möglich ist, sicher.

> Obwohl der Ansatz von GNU-Gettext auch seine Berechtigung hat, und
> dieses Detail regelt, ohne dass der Übersetzer mit Programmcode in
> Berührung kommt. Das ist aber eher bei den String im User-Interface
> sinnvoll, denn der technischen Dokumentation *will* man ja gerade als
> Übersetzer auch den Quellcode vor sich haben, und nicht nur blind einen
> englischen Text Satz für Satz übersetzen.

Ja, Sourcen braucht man (aber gettext kann man auch nicht unbedingt
blind übersetzen, also nicht alle Meldungen). Das ist oft ein Problem,
weil Übersetzer meist keine Sourcen kennen ;) Und natürlich auch ein
Wartungsproblem. Eigentlich dürfte man nur automatisch übersetzen
(Programm) wegen DRY.

Passend zur LaTeX-Argumentation müsste man fordern, dass man den
englischen Text halt so schreibt, dass er gut automatisch in alle
geforderten Sprachen übersetzbar ist (oder in einer Übersprache
dokumentieren). Ist IMHO auch unrealistisch, aber kommt vielleicht
irgendwann (in 25-100 Jahren).

> > Dokumentationsstruktur hat IMHO nichts mit Klassenstruktur zu tun. APIs
> > "per Funktion" bzw. "per Methode" zu dokumentieren, ist oft doof. Das
> > sieht man an der offiziellen JavaDoc gut. Das Interessante steht meist
> > in packages oder classes.
> 
> Das stimmt auch wieder.
> 
> > Dass "String message" die Nachricht ist etc
> > ist meist nicht so überraschend...
> 
> Ja, das ist schade, wenn da nur Offensichtliches steht. Aber man kann
> genauso gut auch auf Gefahren hinweisen, die genau mit dieser Methode
> zusammenhängen. Oder Beispiele liefern, die interessante Randfälle der
> Methode/Funktion beleuchten. Sowas spezielles passt nicht in eine
> Klassen- oder Paket-Doku. Gerade dafür gibt's ja die funktionsbasierten
> Docstrings.

Ja klar. Wenn message "irgendwas" ist und keine weiteren Bedingunen
braucht, sollte man es IMHO überhaupt nicht dokumentieren (verwirrt dann
weniger, als wenn seitenlang beschreiben ist, dass der String ein String
ist ;)). Ausnahmen, Sonderfälle, Bedingungen etc. sind hier natürlich
prima aufgehoben, finde ich auch, ja.

> > Natürlich kann so eine Aufteilung manchmal helfen, klar. Allerdings
> > hat man ja oft ganze Klassen, die Implementierungsdetails darstellen
> > (und in der Benutzerdoku maximal als "Do not use" auftauchen).
> 
> Bei EpyDoc landen die internen Python-Module und -Klassen im
> private-Teil und werden als Ganzes aus der public-Doku entfernt.
> 
> Das ist es doch, was du meinst, oder? Schade, dass man in Java
> keine Klassen / Module / Pakete als "intern" markieren kann. In C++
> geht das ja wieder, da sind das einfach alle Klassen, die nicht im
> Haupt-Header auftauchen. Das ist nicht schön, aber prinzipiell geht's.
> Oder kann Doxygen damit nicht umgehen?

Erstmal zu C++.

Was ist ein Haupt-Header?

Ein nettes fieses Beispiel ist z.B., dass ich in einer lib eine
"Implementierungsdetail-Basisklasse" hab. Könnte man natürlich mit
Aufwand als member verstecken und im Header nicht definieren (sondern
nur ein forward machen), aber dann braucht man wieder source code
generierung, weil jede Kindklasse das so wrappen müsste. Also
pragmatisch: einfach beerben und gut ist. Diese Basisklasse soll ein
"lib user" nicht benutzen, beerben oder Methoden daran aufrufen.
Eigentlich "gibt's die ja gar nicht".

Andere Libs brauchen aber eigene Kindklassen und beerben auch die
Implementierungsdetail-Basisklasse. Na klar, wie sonst.

Der "Scope" wäre hier ca:
- Sichtbar für alle (weil Basisklasse, braucht der Compiler wegen
  sizeof() etc.)
- uninteressant für "einfachen Benutzercode"
- doch interessant für "spezialisierenden/erweiternden Code"

Damit kann man erstmal nicht umgehen, weil man ja nicht weiss, was
welcher Doku-Leser nu gerade braucht. Also schreibt man erstmal alles
rein. Nee, ICH mach das so. Da steht auch dran, wann man es benutzen
soll und wann lieber nicht, falls man darüber stolpert. Sollte man aber
gar nicht, weil die Beispiele etc. das alles schön verschweigen.



In Java gibts "interne" Klassen; die mit dem "package scope". Aber das
ist IMHO auch nur so ein Bug, der als Feature verkauft wird. Das
verhindert Spezialisierungen von anderen Paketen aus, wo man sich (wie
bei den Files) fragt, warum einem die Programmiersprache vorschreibt, wo
man was zu implementieren hat (was im Einzelfall vielleicht eben falsch
ist).

Das führt dann dazu, dass man von der Vielzahl der Klassen doch wieder
nicht so genau weiss, welche man nu nehmen (oder erstmal lesen) soll.

Also macht man ein Beispiel oder Tutorial oder eine Einführung. Am
besten alles :).

> > Methoden müssen vielleicht auch public sein, weil bestimmte andere
> > libs diese Aufrufen können müssen. Die Sichtbarkeitsregeln sind ja
> > sehr primitiv (public, protected, private z.B.).
> 
> In C++ gibt's genau dafür friend-Klassen. In Java hat man natürlich
> ein Problem.

Na ja, friend ist ja auch blöd. Also, ist schon hilfreich für ganz
bestimmte Fälle (nämlich für sehr "private" glue-classes oder sowas),
aber für paketübergreifende Spezialisierung nicht so. Da weiss man ja
nichtmal, ob das Paket vielleicht einen namespace nimmt, also kann man
das friend gar nicht sauber ranschreiben...

Ausserdem hat friend ja das gleiche Problem: es gilt für alle (mit
diesem Namen). Von der Logik her hat man aber eher "Gruppen". Aber man
will ja bei scope Rules auch nicht gleich bei einem
Unix-Stil-Rechtesystem landen :)

> > Da sollte man nicht auch noch die Doku dran festmachen. Oft gibts
> > viele public Methoden, von denen der Benutzer im "Normalfall" nur
> > eine Handvoll aufrufen "sollte". Aber manchmal braucht er vielleicht
> > auch mehrere, besonders bei libs auf einer höheren Ebene oder so.
> 
> Klingt mehr nach mangelnden Ausdrucksmitteln der Programmiersprache
> als nach Dokumentations-Problemen.

Na ja, das ist doch normal. Die Anforderungen (Reihenfolgen,
Detaillevels, ...) hängen halt von der Sicht ab.

> > Didaktisch, genau. Ich find, der Normalfall sollte sein, dass Beispiele
> > einen (den) Standardanwendungsfall zeigen, oder einen "Gutfallablauf"
> > oder sowas in der Art. So sieht man oft gleich, wie ungefähr das
> > funktioniert und hat einen prima Startpunkt.
> 
> Wenn sie außerdem gleich als Testcode dienen, hat man eher die
> Motivation, viele zu schreiben, weil man dann die (meist
> umständlicheren) Unit-Tests sich sparen kann. So profitiert jeder
> davon.

Versteh ich nicht; wenn unit tests umständlich sind (--> sein müssen,
sonst wäre es ja ein Bug), wie kann man sie dann durch Beispiele
ersetzen?

Meine unit tests sind oft im Gegensatz zu Beispielen recht
"tabellengesteuert", also mit Tabellen für Input und Erwartungswert (das
kann ein File oder ein Array als Sourcecode sein, egal). Das ist
natürlich kurz und knapp, aber nicht so verständlich wie ein "lineares"
Beispielprogram.

Würde also eher die Beispiele als "umständlich" bezeichen (und als
"hardcoded", weil die Werte wohl nicht einstellbar sind etc).

http://en.wikipedia.org/wiki/Literate_programming

hat ein Beispiel a la:

- print text Let's work out the area of a circle.
- newline
- print text Please enter the radius of the circle in furlongs:
- store input
- multiplyby value
- multiplyby 3.14159

usw. 

Das soll Literate_programming sein?! 

Ist doch ein Witz, ist doch auch bloss ne formale (durch den Interpreter
definierte) Sprache. Ob nu "store input" oder "read input" (bash) oder
"read(input)" bzw.  "input.store()" oder "store(input)" (C++, Java) ist
doch nu wirklich egal.

Kenn mich da ja nicht so aus, aber klingt jedenfalls komisch.

An doxygen wird kritisiert, dass eine Umordnung nicht möglich sei. Ich
finde, da geht schon ne ganze Menge. Weiss ja nicht, was genau da fehlt.
Ich finde bei doxygen doof, dass ich keine "interne Sicht" erzeugen
kann, die auch die internen Kommentare hat. Obwohl das bei HTML geht,
weil man die Quelltexte als hypertext kriegt - mit Kommentaren. Ist
schon fast das richtige, nur "komisch" formatiert.

Bei Literate_programming finde ich überhaupt nichts von Sichten und
halte es daher für ein viel zu schwaches Konzept.

Ich finde es essentiell, dass verschiedene Sichten beachtet werden. Mit
Doxygen geht das immerhin eingeschränkt.

> (Ja, ich bin ziemlich begeistert von Pythons doctest, das ist eine sehr
> kreative, einfach geniale Idee gewesen.)

Ja, ist schön, wenn geprüft wird, dass der Beispielcode compiliert und
funkioniert.

> > > >   Didaktisch gut heisst oft, die API aus praktischer Benutzungssicht
> > > >   zu beschreiben. Das ist aber ungünstig als Referenz... 
> > > 
> > > Ich sehe da keinen allzu großen Widerspruch. Natürlich ist die API-Doc
> > > hauptsächlich eine Referenz. Aber ganze Klassen oder Module haben doch
> > > ebenfalls Kommentare, und die kann man super nutzen für einführende
> > > Worte und kleine Gesamt-Beispiele.
> > 
> > Ja, genau. Aber hier gibt es Grenzen. Doxygen kann immerhin "pages",
> > schon mal sehr schön, nur leider sind die "Anhang". Aber in hypertext
> > Dokumenten (PDF, HTML) ist das Recht egal. Doxygen kann eine "mainpage",
> > ganz wichtig. Die kann man gliedern. Allerdings kommt dann hier ein
> > "Grossteil" der "wichtigen" Doku rein. Gleichzeitig schränkt einen
> > Doxygen ein: Tabellen sind immer einfach und schlicht, Grafikeinbindung
> > ist mindestens "umständlich" usw. Da hat man dann oft neben der
> > Doxygen-Doku weitere Dokumente. Eine Spezifikation (im Prinzip oft die
> > API ohne Details, wenn die API gut aber knapp ist), vielleicht noch was
> > mit Hintergrundinfos zum Lösungsansatz etc. 
> 
> Das sind aber Doxygen-spezifische Probleme.

Nein, das glaube ich nicht...

> Ein selbstgestricktes Literate-Programming würde dir technisch alle
> Freiheiten geben, die du brauchst.
> 
> Gibt es auch *grundsätzliche* Probleme, wegen denen die Benutzung
> einer API nicht gemeinsam mit der Referenz geschrieben werden
> kann/sollte?

Wie soll denn eine Tabelle nu formatiert werden usw.? Wenn das
automatisch ginge, würde es ja schon mal jemand implementiert haben.
Fakt ist aber, dass es diverse LaTeX packages gibt und auch sämtliche
Office-Programme nicht in der Lage sind, Tabellen immer richtig
automatisch zu formatieren (unter anderem).

Ich glaube, automatisch geht halt einfach nicht. Halbautomatisch (wie
z.B. Word) geht halb. Manuell (LaTeX) kann schöne Ausgaben erzeugen.
Vollautomatisch (HTML Druck) macht mehr oder weniger Mist.

> > Meiner Erfahrung nach macht sich folgendes gut:
> > 
> > - Powerpoint (od ähnl) Präsentation mit Überblick, Marketing-Charakter,
> [...]
> > - Eine Webseite, wo man abschätzen kann, ob und wie das hinter dem
> [...]
> > - Release Notes.
> [...]
> > - Allgemeine (untypisierte) Infos. Kann ein Dokument oder auch eine
> >   Webseite sein - oder ein README oder INSTALL. 
> [...]
> > - nu endlich kommt API docu :-)
> [...]
> > - Historie der Software nicht (kaum) in den Sourcen selbst sondern im
> >   SCM (CVS, SVN).
> > 
> > Stellt sich wieder die Frage, ob das noch alles von einem Tool gemacht
> > werden kann.
> 
> Nein, ich denke, das ist machbar. Statt Powerpoint kannst du genauso
> auch PDF erzeugen, also läuft's letztlich auf LaTeX, HTML und Plaintext
> als Dateiformat hinaus, wenn's nicht zu sehr verspielt sein soll.
> Die Werkzeuge sind alle da, nur den Klebstoff muss man sich hacken.
> Und das ist dann dein "Tool". Die Frage, die *ich* mir stattdessen stelle:
> 
> Kann das alles aus einer Quelle erzeugt werden?

Wie gesagt, ich glaub es nicht (komische Sachen oder einfach .tgz oder
so zählen natürlich nicht). Natürlich kann man ein LaTeX Verzeichnis
machen, wo jede Datei eine Ausgabe erzeugt, aber das hilft ja überhaupt
nichts :) 

> Bis dahin genügt eigentlich der Hinweis: Wenn du eine "OrderedByCreation"-
> Klasse brauchst, merkst du das auch.  :-)

Ja, klingt plausibel (für die Doku, nicht für den Bedarf an sich). Kann
man IMHO auch so ranschreiben: "If you don't know what this is about,
you are lucky and don't need to bother" oder sowas.

> > Wenn ich Entwickler bin, frage ich mich vielleicht, wie ich
> > camelcase um einen Parameter erweitere, der angibt, ob der erste
> > Buchstabe klein sein soll (oder weiss ich was). Über interna steht da
> > nichts (was ja auch gut so ist, ist ja eine Benutzer Doku).
> 
> Das finde ich nicht. Die Implementierung ist ein 1-Zeiler, und
> vollkommen "straight forward". 

Ja, gut, wenn wir das schon thematisieren: Einzeiler als Libfunktionen
mag ich selten. Gibt komplexe Sachen, wo's Sinn macht, aber wenn am Ende
soviel logischer Overhead für eine Zeile Code gebraucht wird, die von
einer Zeile Code aufgerufen wird, hat man es vermutlich übertrieben :)

(Also, hier ist sowas wie

   return u"".join(word[:maxlen].capitalize() for word in ustr.split())

natürlich nicht gemeint, das sind viele Zeilen (weil man meist eine
Anweisung pro Zeile haben möchte, bei fire-and-forget Scripten natürlich
nicht, bei Scriptsprachen selbst ist die Grauzone :)).)

> Eine solche "Erweiterung" schreibt man am besten, indem man eine
> zweite Funktion schreibt, die die erste aufruft und beim Ergebnis das
> erste Zeichen auf Lowercase setzt.

(Jajaja, ich behaupte ja nicht, dass mein Beispiel gut wäre :)).

> Die meisten Routinen haben eine überraschend einfache Implementierung.
>     http://www.profv.de/vopu/vopu.py
> Die Docstrings sind im Schnitt 3-4 mal so groß wie die Implementierung.

(Das ist wohl Geschmackssache. Ich mag Sourcen, die auf Lesbarkeit und
nicht Sourcecodegrösse optimiert sind. Hat natürlich alles Vor- und
Nachteile)

> > Allgemeines steht da auch nicht. Wann wurde das entwickelt,
> 
> Ist das wichtig? Na gut, dass es für Python-2.4 geschrieben ist, sollte
> noch dastehen. 

Ahh, Python. ;)

> Aber ansonsten ist da die Jahreszahl bei der Copyright- Angabe?

Brauchte man in DE nie und in US wohl inzwischen auch nicht mehr, soweit
ich weiss. Die Jahreszahl muss i.d.R. den Beginn nicht das Ende der
Entwicklung bezeichnen, aber meist sieht man ja Änderungen/Erweiterungen
als kleine Neuentwicklungen und schon kann man ranschreiben, was man
will.

> Braucht man mehr?

Kommt drauf an, wie immer :)

> > welche Version ist das,
> 
> In der Modul-Doku findest du
> 
>     __version__    "1.7"
> 
> Das ist wohl eine Konvention. Warum EpyDoc das nicht auswertet, weiß ich
> nicht. Vielleicht sollte ich das wirklich lieber in den Modul-Docstring
> hinein schreiben.

Diese Version wird bei jeder Änderung erhöht? Oder ist das eher eine
API-Version?

Na ja, kommt eh drauf an, was man für Anforderungen hat. Gibt ja viele,
die auf 1.0.0-rc4-myfork oder sowas als Version stehen, was dann
vielleicht nichtmal eindeutig ist. Kommt halt darauf an, stimmt.

na ja, stimmt, über private kann man sich die angucken, aber so ideal
ist das nicht, oder?

> Den gibt es auch nicht. Eines der Beispiele kombiniert wohl zwei der
> Klassen, aber das ist eher Zufall.
> 
> Gleich der erste Satz der Modul-Doku sagt doch:
> | This module contains various functions and classes which are very
> | useful for my daily work with Python.
> 
> Es ist also ein Sammelsorium von Hilfs-Klassen und -Funktionen, die
> man wiederverwenden könnte. Zum Teil sind es einfach Sachen, die es in
> den entsprechenden Python-Paketen einfach nicht gibt, obwohl sie
> praktisch wären.

(na gut, wenn Du es so hart hören willst: so macht man keine Module ;))

Für mich grenzt das immer noch nicht ab, was (z.b: an neuen Funktionen)
da rein und was da nicht rein gehört. Da könnte ich ja "alles"
reinpacken, sozusagen. Also, Du (weil "for my daily work") :)

Na ja, ist nicht so günstig das Beispiel. Klar, wenn Du Dir eine private
Sammlung anlegst, musst Du strenggenommen gar nichts dokumentieren,
solange Du es Dir merkst ;)

> > Die Sourcen guck ich mir nicht weiter an, hab eh
> > keinen Plan von phyton. Obwohl ich mich z.B. Frage, ob es den Aufriss
> > eines StrinStreams Wert ist, der scheinbar nur "self.content += str"
> > implementiert (falls ich die Sourcen richtig verstehe, was mangels
> > Python Kenntnissen recht unwahrscheinlich ist).
> 
> Nein, das hast du völlig richtig erkannt. Die Implementierung ist
> trivial, aber solch eine Klasse gab es in Python noch nicht
> (mittlerweile glaubich gibt's das schon). Das Interface ist
> entscheidend.

aha... naja, wirkt auf mich overdesigned. Aber vielleicht auch
Geschmackssache.

> Es gibt Funktionen, die wollen etwas ausgeben, in bieten es leider
> nur an, in eine Ausgabedatei (genauer: einen Stream) zu schreiben.
> Will ich lieber einen String, brauch ich solch eine Hilfsklasse.

Wieso nicht einen string nehmen, wenn man einen string will?

> Als ich sie geschrieben hatte, fiel mir auf, dass sie mit dem konkreten
> Projekt eigentlich nichts zu tun hat. Und genau solche Dinger schiebe
> ich nach VoPU, dafür ist es da. :-)

Würd ich wohl eher nicht so machen, weil das Projekt ja dann wegen einer
Zeile von VoPU abhängt. Aber oft wird sowas mit der Zeit ja mehr :)


> Eben. Wieso sollte jemand diese Funktion jemals gebrauchen können,
> wenn er nichtmal weiß, was CamelCase ist.

[Newton-Beispiel]

Ja, Du hast vollkommen Recht.

> > Release-Informationen fehlen völlig (welche Version, von wann,
> > freigegeben oder experimentell, getestet oder nicht, welche
> > Qualitätsanforderungen, welche Sprache überhaupt usw. Welche
> > Funktionen würde ich hier hinzufügen, welche anderen hingegen wären
> > hier eher falsch einsortiert etc.
> 
> Danke für den Hinweis. Aber ehrlich gesagt wüsste ich nicht, was ich zu
> diesen Punkten schreiben sollte.
> (Und die Versionsnummer steht ja da)

Ja, stimmt. Macht auch keinen Sinn, wenn es gar keinen Prozess gibt,
stimmt. Muss man also gar nicht freigeben und man hat den Kram nicht :)
Wobei das strenggenommen auch für die Doku an sich gilt (es steht
nirgens, dass man sie braucht - macht sich nur besser, wenn man eine hat
:)).

> > Macht hier "für Dich" natürlich keinen Sinn, Du weisst das ja auswendig
> > bzw. spielt es keine Rolle (das gilt vermutlich für die gesamte Doku
> > ;)), aber wenn andere die Lib nutzen wollen würden, fehlten halt noch
> > viele Infos.
> 
> Achso? Wenn ich eine fremde Lib benutze, schaue ich kaum auf diese
> Dinge. Ich schaue auf die Lizenz (ob ich sie überhaupt nutzen *darf*),
> später vielleicht auf die Versionsnummer (wenn ich sie auf verschiedenen
> Rechnern vorfinde), und in die Doku/Howtos, ob sie überhaupt das macht,
> was ich brauche.
> 
> Sicher ist auch der Status (stable/...) interessant, aber doch erst bei
> großen Projekten, oder?

Weiss nicht... Geschmackssache. Ich würde jedenfalls nichts benutzen,
was durchdacht *und* sauber entwickelt und gepflegt wird. Ich möchte ja
nicht in zwei Jahren dastehen und geht nicht weiter weil lib nicht mehr
da oder so. Also vielleicht eine Frage der Professionalität, damit man
nicht aus Versehen eine Lib von Max Mütze benutzt oder so, der nur
zufällig ne brauchbare Funktion geschrieben hat oder so. Vielleicht auch
nur eine Vertrauensbildende Massnahme...

Jedenfalls ärgerlich, wenn man dann irgendwelche Programme nicht mehr
kriegt (oder die neuen spinoffs in ganz andere Richtungen gehen, was
schlankes plötzlich killer ist oder so).

> > Es gibt keine Suche, dass ist bei einem "Webserver-Dienst" eigentlich
> > Schade. Der Index enthält neben vielen komischen (privaten?) Funktionen
> > (?) und viele __init__s nicht einen "menschlich-aussehenden Begriff".
> 
> __init__ ist der Konstruktor. Das weiß aber ein Python-Programmierer.
> Auch __cmp__, __delattr__, etc. kennt jeder. Das sind überladene
> Operatoren.

Na ja, schon klar, aber im Index müsste dann halt noch der Klassenname
gleich dahinter stehen, so mit Erklärung ist's IMHO irgendwie komisch.
Naja, Geschmackssache. Ein Index hat für mich jedenfalls normalerweise
keine Erklärungen (sonst ist es eine Glossary ;)).

> Die Grundidee dahinter finde ich aber gar nicht so schlecht. Das löst
> das Problem, auf die offizielle Python-Doku zu verlinken. (man weiß
> ja nicht, ob derjenige das online oder offline liest, und ob man auf
> python.org muss, oder auf /usr/share/python...)

Ja klar.

> > Ich würde sowas wie "URL Verarbeitung" oder "Iterating objects" oder so
> > erwarten. Man weiss ja oft weder, ob eine bestimmte "gesuchte"
> > Funktion existiert, geschweige denn wie sie heisst...
> 
> Das verstehe ich nicht. Was meinst du mit "URL Verarbeitung" oder
> "Iterating objects"?

Na, wenn ich in einer Riesenlib suche, und mich noch erinnere dass es
irgendwas in der Art gab, aber natürlich ncht mehr, wie's heisst oder
vielleicht nur mal gucken will, ob es sowas schon gibt (weil ich das
erwarte oder so), dann gucke ich ja nicht unter split_labeled_uri nach,
sondern nach "URI, labeled" oder sowas (Was auch immer das sein mag,
keine Ahnung).

> Meine Applikationen nutzen in der Regel mehrere Funktionen der vopu.py,
> und ich möchte, dass eine Applikation von den Verbesserungen einer
> anderen profitiert, wenn sie möchte.
> 
> Daher mache ich das so: *In* die Applikation kommt eine Kopie der
> vopu.py, es ist ja nur ein Modul, dem ist es egal, wo es liegt. Anhand
> der VoPU-Versionsnummer weiß ich auch immer, womit ich es zu tun habe.
> 
> Entwickle ich die Applikation weiter, behält sie ihre alte vopu.py, das
> erspart Kompatibilitäts- und Distributionsprobleme. Erst dann, wenn ich
> für die Applikation eine neue VoPU-Funktion brauche oder schreibe,
> kriegt diese eine Applikation eine aktuelle vopu.py.
> 
> Haben zwei Python-Pakete eine vopu.py, nimmt jede ihre eigene, denn
> die vopu.py liegt ja im jeweiligen Package, also in einem eigenen
> Verzeichnis und damit einem eigenen Namespace.
> 
> Das ist also sehr einfach gehalten, und auch für größere Libs wird
> generell empfohlen, eigene Libs gebündelt mit der Applikation zu
> vertreiben, solange, bis die Lib wirklich *sehr* weit verbreitet ist
> und sich ein extra Paket lohnt. Das ist eine Python-Richtlinie, und
> zwar meiner Meinung nach eine ziemlich gute. Kein Konflikte, keine
> Kompatibilitätsprobleme.

Aha, ist ein etwas... erm... interessanter Ansatz, finde ich. Ich ging
immer davon aus, dass man Module eben gerade nicht kopieren will. Kann
mir hier auch nicht gut vorstellen, wie das geht. Haste zwei Versionen
und jede braucht ein Bugfix, aber update geht nicht, weil beide ziemlich
unterschiedlich etc pp.
Kompliziert. Aber anderes Thema :)

> Jede größere Applikation besteht zum Teil aus eigenen general-purpose-
> Bibliotheken. Aber nur bei den wenigstens davon lohnt es sich
> wirklich, sie getrennt zu vertreiben. Das ist ja immer sowohl
> technischer als auch organisatorischer Mehraufwand.

Genau. Daher würde ich für Einzeiler halt versuchen, die libs an sich zu
vermeiden. Kopieren halte ich für gefährlich; jemand anders ändert da
nachher noch was oder so. mmm... Dann gibts zwei 1.8er Versionen oder
so. Na ja, Geschmackssache :)

oki,

Steffen

-- 
Dieses Schreiben wurde maschinell erstellt,
es trägt daher weder Unterschrift noch Siegel.





Mehr Informationen über die Mailingliste linux-l