Was sind Beispiele für Kommentare, aus denen hervorgeht, warum und nicht wie oder was? [geschlossen]


78

Zunächst möchte ich mich in dieser Frage von der Polemik fernhalten, ob das Kommentieren von Quellcode gut oder schlecht ist. Ich versuche nur klarer zu verstehen, was die Leute meinen, wenn sie über Kommentare sprechen, die Ihnen sagen, WARUM, WAS oder WIE.

Wir sehen oft Richtlinien wie "Kommentare sollten Ihnen sagen, WARUM; Code selbst sollte Ihnen sagen, WIE". Es ist leicht, der Aussage auf abstrakter Ebene zuzustimmen. Allerdings lassen die Leute dies normalerweise wie ein Dogma fallen und verlassen den Raum ohne weitere Erklärung. Ich habe gesehen, dass dies an so vielen verschiedenen Orten und in so unterschiedlichen Kontexten verwendet wird, dass es so aussieht, als könnten sich die Leute auf den Slogan einigen, aber sie scheinen ganz über verschiedene Dinge zu reden.

Zurück zur Frage: Wenn Kommentare sagen sollten, WARUM, worüber reden wir dann? Ist das der Grund, warum dieses Stück Code überhaupt existiert? Ist es das, was der Stückcode tun soll? Ich wäre sehr dankbar, wenn jemand eine klare Erklärung abgeben und dann einige gute Beispiele hinzufügen könnte (schlechte Beispiele werden nicht wirklich benötigt, können aber als Kontrast verwendet werden).

Es gibt viele Fragen, ob Kommentare gut oder schlecht sind, aber keine, die sich mit der spezifischen Frage befassen, was gute Beispiele für Kommentare sind, die Ihnen sagen, WARUM.


36
Manchmal sprechen die besten Kommentare WARUM NICHT. Ich bin einmal auf ein komplexes Stück Code gestoßen, das so aussah, als könnte es leicht vereinfacht werden. Der Kommentar erklärte, warum diese offensichtliche Vereinfachung in diesem speziellen Fall nicht funktionierte (weil der ursprüngliche Entwickler es bereits ausprobiert hatte).
Dan Pichelman

6
There are many questions on whether comments are good or bad, but no one that addresses the specific question of what are good examples of comments that tell you WHY. Wenn jeder ein gültiges Beispiel liefert, dann sind alle die richtigen Antworten. Das Format dieser Website soll einen Frage- und Antwortprozess ermöglichen, bei dem nicht alle Antworten gleich sind.
David Kaczynski

Guter Punkt, @ David-Kaczynski. Was schlagen Sie vor?
Rick

1
Ich kann mir keine Möglichkeit vorstellen, die Frage so zu formulieren, dass ein einzelnes Beispiel oder eine verallgemeinerte Taktik die "beste" Antwort sein kann. Es gibt einen Chat-Teil von p.se: chat.stackexchange.com/rooms/21/the-whiteboard , aber für Ihre Frage gibt es wahrscheinlich ein besseres Forum. Um ehrlich zu sein, sieht es so aus, als ob Ihre Frage von der Community hier positiv beantwortet wird. Es lohnt sich also wahrscheinlich nicht, sich darüber Gedanken zu machen. Der beste Ratschlag, den ich geben kann, um Beispiele für nützliche Kommentare zu finden, ist das Durchsuchen beliebter öffentlicher Git-Repositorys.
David Kaczynski

Antworten:


62

Das häufigste und markanteste Beispiel sind Kommentare zu verschiedenen Problemumgehungen. Zum Beispiel dieses:

https://github.com/git/git/blob/master/compat/fopen.c :

/*
 *  The order of the following two lines is important.
 *
 *  FREAD_READS_DIRECTORIES is undefined before including git-compat-util.h
 *  to avoid the redefinition of fopen within git-compat-util.h. This is
 *  necessary since fopen is a macro on some platforms which may be set
 *  based on compiler options. For example, on AIX fopen is set to fopen64
 *  when _LARGE_FILES is defined. The previous technique of merely undefining
 *  fopen after including git-compat-util.h is inadequate in this case.
 */
#undef FREAD_READS_DIRECTORIES
#include "../git-compat-util.h"

Weitere Beispiele finden Sie sicherlich in Git- und Linux-Quellen. Beide Projekte versuchen, diese Regel zu befolgen.

Ich empfehle außerdem, diese Regel bei Commit-Protokollen noch strenger einzuhalten . Bei Codekommentaren kann es vorkommen, dass Sie den Code korrigieren, aber vergessen, den Kommentar zu aktualisieren. Mit der Menge an Code in einem normalen Projekt wird dies früher oder später garantiert. Zum anderen ist das Commit-Protokoll an die jeweilige Änderung gebunden und kann über die Funktionen "Annotate" / "Blame" des Versionskontrollsystems abgerufen werden. Auch hier haben Git und Linux einige gute Beispiele.

Schau dir zB dieses Commit an . (hier nicht kopieren, es ist zu lang). Es enthält vier Absätze, die fast die ganze Seite (und ein bisschen mehr als die Bildschirmseite) umfassen und beschreiben, was genau falsch war und warum es falsch war. Sie verwenden Kommentare wie diese für zwei Zwecke:

  1. Alle eingereichten Änderungen werden überprüft und das Festschreibungsprotokoll muss dem Prüfer die Änderung erklären.
  2. Wenn ein Fehler gefunden wird, werden die relevanten Protokolle mit "Spitzhacke" oder "Schuld" abgerufen, um zu vermeiden, dass zu einem früheren, auch falschen Verhalten zurückgekehrt wird.

(Hinweis: Es dauerte höchstens 10 Minuten, bis ich das Git-Repo nach dem Zufallsprinzip durchsucht hatte, um diese beiden Beispiele zu finden. Es wäre also sicher einfach, dort mehr zu finden.)


29

In einem Kommentar erfahren Sie, warum der Code begründet wurde. Beispiel:

// We need to sync the values if the temp <doodad> GUID matches one of the active <doodad>'s
// GUID, as the temp <doodad> has the most recent values according to the server and said 
// values might have changed since we added the <doodad>. We want a user to be able to <foo> 
// the <doodad> whenever, which means those values must be accurate.
for (doodad in doodads) {
    if ([doodad guid] == [tempDoodad guid]) {
        [doodad updateFromDoodad:tempDoodad];
        break;
    }
}

In einem Kommentar erfahren Sie, wie der Code funktioniert.

// Loop through our <doodads> and check for a GUID match. If it matches, copy the new values
// on the <doodad> that matches 
for (doodad in doodads) {
    if ([doodad guid] == [tempDoodad guid]) {
        [doodad updateFromDoodad:tempDoodad];
        break;
    }
}

Der Unterschied ist, dass ein Betreuer sich den ersten ansehen und sagen kann: "Oh, das könnte also veraltet sein!" Im zweiten Fall hat der Betreuer einen Kommentar, der Ihnen nichts sagt, was der Code selbst nicht preisgibt (unter der Annahme guter Variablennamen).

Hier ist ein Beispiel aus der Praxis eines Warum-Kommentars aus einem iOS-Code, an dem ich gearbeitet habe, um eine Gateway-Adresse zu erhalten (oder eine vernünftige Vermutung dafür). Ich hätte einfach die Kommentare hinterlassen können, die Dinge wie "Initialize the receive socket" sagten, aber das würde einem Betreuer (oder mir in Zukunft) nur sagen, was passiert ist, und nicht, warum ich diesen seltsamen Fehler machen musste, um die Gateway-Adresse im zu bekommen erster Platz.

/*
 We're going to do something really hacky here and use a custom partial
 implementation of traceroute to get our gateway IP address.

 [rant removed - irrelevant to the point]

 There's no good way to get at the gateway address of an iDevice
 right now. So, we have two options (per https://devforums.apple.com/message/644915#644915 ):
 1. Get at and parse the routing table (like netstat -rn, or route -n)
 2. Do a traceroute and grab the IP address for the first hop

 As far as I can tell, the former requires <sys/route.h> from the Mac OS X
 header files, which doesn't seem like a good idea to me. Also, there's a
 thread on the Apple Developer forums that seems to imply that header isn't
 in iOS for a reason (https://devforums.apple.com/message/774731#774731 ).

 So when we send our request with a TTL of one it will survive a single hop
 to the router and return, triumphant, with the router's IP address!

 Viva la kludge!

 PS: Original source was the below SO question, but I've modded it since then.
 http://stackoverflow.com/questions/14304581/hops-tracing-ttl-reciveform-on-ios/14304923#14304923
 */

// Default to using Google's DNS address. We used to try checking www.google.com
// if reachability reported we had internet, but that could still hang on routers
// that had no internet connectivity - not sure why.
const char *ip_addr = [kGoogleDNS UTF8String]; // Must be const to avoid undefined behavior
struct sockaddr_in destination,fromAddr;
int recv_sock;
int send_sock;

// ... more code follows

4
Das erste Beispiel ist sehr ausführlich und enthält einen Großteil des "Wie". Es sollte nur "Aktualisiere die <doodads> von temp <doodad>, damit der Benutzer sie jederzeit sicher <foo> kann." Der Rest ist trivial aus diesem oder dem Code zu implizieren. Auch die "Märcheneinführung" in den ersten vier Absätzen des letzten Beispiels ist völlig sinnlos. Ich würde "Viva la kludge!" Verlassen. Es ist lustig und es ist am Ende. Aber der Anfang sind einfach zu viele Wörter, die man durchgehen muss, um zur eigentlichen Erklärung zu gelangen.
Jan Hudec

@JanHudec Angepasst gemäß Ihrem Feedback. Sieh mal nach, oder?
Thegrinner

15
Das Schöne am zweiten Beispiel ist, dass es nicht nur erklärt, warum der Code auf bestimmte Weise funktioniert, sondern auch, warum andere, vernünftige Alternativen nicht verwendet wurden. Dies macht den Code viel wartbarer, da der nächste, der den Code liest und denkt: "Warum kann ich die Routing-Tabelle nicht einfach analysieren?" kann nur den Kommentar lesen. Ferner jemand, der nicht mit einem berechtigten Grunde kommen wird , den Code zu ändern , um mehr darauf verlassen, dass es sicher ist , dies zu tun. Andernfalls hat ein Betreuer Angst, dass eine Änderung in dem (unbekannten) Szenario, das den Kludge inspiriert hat, fehlschlägt.
Brian

18

Ich möchte meine Antwort mit einem Zitat von Jeff Atwood in seinem Blog - Post gemacht Start - Code erfahren Sie , wie, Kommentare Sagen Sie , warum :

Die besten Kommentare sind die, die Sie nicht brauchen

Er stellt auch fest, dass:

Sie sollten sich zuerst bemühen, Ihren Code so einfach wie möglich zu verstehen, ohne sich auf Kommentare als Krücke zu verlassen. Erst an dem Punkt, an dem der Code nicht besser verständlich ist, sollten Sie Kommentare hinzufügen.

Ich stimme vollkommen zu und an dieser Stelle muss ich hinzufügen, dass ich, bevor ich anfangen kann, den Code so einfach wie möglich zu gestalten, den Code zum Laufen bringen und dann mit dem Refactoring beginnen kann. Während des ersten Durchlaufs vor dem Refactoring hilft das Hinzufügen von Kommentaren sehr.

Wenn Sie beispielsweise 3 verschachtelte Schleifen mit zweidimensionalen Hashtabellen verwenden, um eine Tabelle mit Wochentagen zu füllen, während Sie Daten analysieren, verlieren Sie leicht den Überblick darüber, was jemand oder auch Sie selbst getan haben, wenn Sie einige Wochen lang nicht darauf geachtet und plötzlich umgestaltet haben.

[loop1]6oclock -> [loop2]Monday -> [loop3]stage 1 to 4
         -> tuesday-> stage 1 to 4
         ...
         -> Saturday -> stage 1 to 4
    7oclock -> Monday-> stage 1 to 4
        ....etc.

Das obere Beispiel zeigt, wie drei verschachtelte Schleifen vor dem Refactoring funktionieren.
Das Erklären einiger Verzweigungsbedingungen kann helfen, den Code besser zu verstehen, wenn man daran denkt:

// added a zero before the actual day in order for the days always to be 2 digits long.
if( actualDayFuture < 10 ) 
{ 
     actualDayFuture = padIfSingleDigitDate(actualDayFuture); 
}

Sogar einfacher und offensichtlicher Code funktioniert gut mit Kommentaren. Nur um die Dinge für Kollegen und sogar für sich selbst bei der Pflege von Software ein wenig offensichtlicher, klarer oder verständlicher zu machen.

Sicher, XP gibt an, dass Code selbsterklärend ist, aber tut ein einzeiliger Kommentar weh?

Ich finde auch die folgenden Regeln in diesem Blog sehr hilfreich:

  • Verstehe das Material, bevor du schreibst
  • Schreiben Sie, als wäre Ihr Publikum ein Viertklässler
  • Überlegen Sie, wie die Leser Sie falsch interpretieren könnten

Jeder, der wieder in seinen eigenen Code oder in einen anderen oder sogar älteren Code zurückkehren muss, weiß, dass dies Kopfschmerzen verursachen kann. Anstatt also faul zu sein oder zu versuchen, ein Übercodierer zu sein, der nichts oder nur sehr wenig kommentiert, sollten Sie sich selbst oder einen armen Kerl, der Ihren Code warten muss, das zukünftige Leben erleichtern, indem Sie die angegebenen Regeln befolgen.

Auch viele Programmierentscheidungen werden bei Überprüfungen angezweifelt, und es ist nicht immer klar, warum einige Teile so geschrieben wurden, wie sie waren, auch wenn einige Codeabschnitte aufgrund eines schwerwiegenden Fehlers, der bei der Verwendung des Codes im Laufe der Jahre festgestellt wurde, für das Funktionieren eines Programms von entscheidender Bedeutung sind . Also, um Sie nicht alle mit einem Wort zu langweilen, schließen Sie mit einem letzten Zitat aus acmqueue :

Eine vorherige, übersichtliche und umfassende Dokumentation ist ein Schlüsselelement bei der Erstellung von Software, die überleben und sich anpassen kann. Das Dokumentieren nach hohen Standards verkürzt die Entwicklungszeit, führt zu besserer Arbeit und verbessert das Endergebnis. Es ist schwer, von irgendeiner Technik mehr als das zu verlangen.


8
In Ihrem zweiten Beispiel könnte man Kommentare durch Refactoring vollständig entfernen: actualDayFuture = padIfSingleDigitDate (actualDayFuture); Dies ist trivial, aber ein robusteres Beispiel würde von diesem Ansatz profitieren.
Chris Cudmore

4
Ich hätte die Bedingung auch in die Methode verschoben. - Wiederum nicht für etwas so Triviales, aber es erlaubt mir, das Denken über die Fülllogik völlig außer Acht zu lassen. Ich würde Ihr ursprüngliches Beispiel jedoch nicht ersetzen, da dies eine bessere Antwort auf die Frage ist. Es ist eher eine Randnotiz, andere Alternativen zu erkunden.
Chris Cudmore

1
Ad "Sicher, XP gibt an, dass Code selbsterklärend ist, aber tut ein einzeiliger Kommentar weh?": Kommentare sind gut, aber es besteht auch die Gefahr, dass sie überkommentiert werden. Jede Kommentarzeile ist eine, die jemand vergessen könnte, zu aktualisieren, wenn er den Code ändert.
Jan Hudec

1
Ein besserer Weg, dies zu sagen, ist "Die beste Art von Kommentar ist das Fehlen der Notwendigkeit eines Kommentars". Kommentare, die nicht benötigt werden (aber trotzdem geschrieben sind), sind keine guten Kommentare.
Kaz

1
Interessant, dass der Code, auf den verwiesen int directionCode = (x > oldX) ? DIRECTIONCODE_RIGHT : (x > oldX) ? DIRECTIONCODE_LEFT : DIRECTIONCODE_NONE;wird, fehlerhaft ist. Sicher sollte es sein ... (x < oldX) ? DIRECTIONCODE_LEFT : DIRECTIONCODE_NONE;. Gute Kommentarideen - schlechter Code.
Chux

8

Ich neige dazu, Kommentare auf Verweise zu beschränken, in denen eine bestimmte Funktionalität / ein bestimmter Code ausführlicher erklärt wird, oder zu erklären, warum eine bestimmte Art der Programmierung gewählt wird.

In Anbetracht der Tatsache, dass andere Programmierer mit ähnlichen Fähigkeiten Ihren Code verwenden oder lesen, ist es wichtig zu kommentieren, wenn Sie eine andere als die erwartete Methode verwenden, um etwas zu erreichen. Sie können also in einem Kommentar erklären, warum Sie sich für diesen Weg entschieden haben.

Wenn Sie beispielsweise zwei verschiedene Sensoren auf einem Android-Gerät verwenden können und einer nicht Ihren Anforderungen entspricht, können Sie im Kommentar erläutern, warum Sie den anderen gewählt haben.

Das "Warum" sollte also eine Begründung für Ihre getroffenen Entscheidungen geben.


5
Referenzen sind ein gutes Beispiel. // Diese Methode verwendet den Furshclingeheimer-Algorithmus, um den Foobit zu ronsterisieren. Siehe http: // ...
Chris Cudmore

8

Kommentare sollten Ihnen sagen, was der Code nicht tut, und nicht unbedingt durch WARUM , WIE oder WAS abgegrenzt sein . Wenn Sie gute Namen und klar umrissene Funktionen haben, ist es durchaus möglich, dass der Code Ihnen genau sagt, was los ist. Zum Beispiel:

List<LightMap> maps = makeLightmaps(receivingModels);
TrianglePartitioner partition = new Octree(castingTriangles);
List<Photon> photons = firePhotons(lights, partition);

if (photons.Count > 0)
{
      PhotonPartitioner photonMap = new KDTree(photons);
      gatherPhotons(maps, photonMap, partition, lights);
}

Dieser Code benötigt wirklich keine Kommentare. Die Funktions- und Typbezeichnungen machen es leicht verständlich.

Manchmal kann es jedoch schwierig oder unmöglich sein, wirklich fließenden Code wie den oben genannten zu erstellen. Das nächste Codefragment dient beispielsweise zum Auffinden eines statistisch zufälligen Punkts auf einer Kugel. Die Mathematik ist ziemlich undurchsichtig, so dass ein Kommentar mit einem Link zur Erklärung dazu beiträgt, zu erklären, wie es funktioniert. Dies kann in eine Funktion eingebunden werden , die angibt , WAS es tut, ohne dass ein Kommentar erforderlich ist, falls dies mehrmals erforderlich ist. Andernfalls hilft der Linktitel auch in dieser Abteilung.

double randomA = localGenerator.NextDouble();
double randomB = localGenerator.NextDouble();

//http://mathworld.wolfram.com/SpherePointPicking.html
double theta = 2 * Math.PI * randomA;
double phi = Math.Acos(2 * randomB - 1);

Vector3 randomDirection = new Vector3(Settings.ambientRayLength * (float)(Math.Cos(theta) * Math.Sin(phi)),
                                      Settings.ambientRayLength * (float)(Math.Sin(theta) * Math.Sin(phi)),
                                      Settings.ambientRayLength * (float)Math.Cos(phi));

Ein weiteres Beispiel dafür, wann Kommentare Ihnen sagen, was der Code nicht tut, ist die Erläuterung einer Entscheidung. Im nächsten Beispiel sperrt der Code keine nicht-threadlokale Variable in einem Code mit Thread. Es gibt einen Grund dafür und der Kommentar erklärt WARUM . Ohne den Kommentar könnte es sich um einen Fehler handeln oder einfach nicht einmal bemerkt werden.

Random random = new Random();
Parallel.For(0, maxPhotons, delegate(int photonIndex, ParallelLoopState state)
{
    ...
    //I don't actually care if this random number is unique between threads, threadsafty is not that big of a deal
    //  in this case and locking the random object could cause a lot of lock contention
    while (random.NextDouble() > reflectProbability)
    {
        ...
    }
    ...
}

Es könnte vielleicht verbessert werden, zu sagen, warum das zufällige Objekt nicht an erster Stelle innerhalb der parallelen Schleife erzeugt wird. Wenn es keinen Grund gibt, könnte es auch jemanden dazu bringen, mitzukommen und zu erkennen, dass die ganze Idee dumm ist und ein guter Ort zum Refactoring ist.


Ist es sinnvoll, Code so zu beschreiben, dass er keine Kommentare benötigt, wenn den Kommentaren WriteTexteher als vorangestellt wird //?

1
Wie ich in der Antwort sagte, sind Kommentare auch dann nicht erforderlich, wenn es keine Druckanweisungen gab. Ich habe sie jedoch bearbeitet, um die Druckanweisungen zu entfernen, um den Punkt klarer zu machen.
Chewy Gumball

5

Es kann hilfreich sein, verschiedene Arten von "Warum" zu erkennen - insbesondere:

  • Gründe dafür, dass Code, der übermäßig komplex zu sein scheint, bei einer Vereinfachung nicht funktioniert (z. B. kann eine scheinbar überflüssige Typumwandlung erforderlich sein, um sicherzustellen, dass Code in einigen Eckfällen funktioniert).

  • Gründe dafür, dass eine bestimmte einfache Operation, die gefährlich aussieht, tatsächlich sicher ist (z. B. "Unsere Datenabrufroutine meldet, dass ein Dummy-Artikel-Artikel nach dem letzten weniger als alles andere und der Artikel danach größer ist; jeder Artikel, der sortiert werden soll." vor einem anderen wird in einer konsistenten aufsteigenden oder absteigenden Reihenfolge mindestens ein weiteres (möglicherweise Dummy-) Element darauf folgen ").

In vielen Fällen kann ein Kommentar des zweiten Typs in einem Teil des Codes mit einem Kommentar des ersten Typs in einem anderen "übereinstimmen" (z. B. "Während es so aussieht, als ob diese Abfolge von Operationen vereinfacht werden könnte, verlässt sich die Fitz-Routine darauf." der Wongle wird erst wütend gemacht, nachdem der Banderschnatz verschwunden ist. ")


2

Vergiss nicht, wenn du ein Programm schreibst, tippst du nicht einfach nach dem Zufallsprinzip, sondern machst es, weil du ein Modell dafür hast , was du willst , sei es in einem formellen Dokument oder nur in deinem Kopf. Das Zeug in deinem Kopf ist genauso real wie Software / Daten in einem Computer (und es ist genauso wahrscheinlich, dass es Fehler enthält).

Jemand, der Ihren Code liest, hat dieses Modell möglicherweise nicht im Kopf, sodass Kommentare dazu dienen können, ihm mitzuteilen, wie das Modell war und in welcher Beziehung der Code dazu steht. Ich denke, das ist es, was mit "warum" gemeint ist. Natürlich ist es gut, den Code selbst so selbsterklärend wie möglich zu gestalten, aber das ist nicht immer gut genug. Beispiel:

// transform the x,y point location to the nearest hexagonal cell location
ix1 = (int)floor(0.5 + x + y/2);
iy1 = (int)floor(0.5 + y);

Darüber hinaus ändert sich das Modell im Laufe der Zeit, und diese Änderungen müssen in den Code übertragen werden. In den Kommentaren muss also nicht nur das "Warum" eines Codes angegeben werden, sondern auch, wie dieser als Reaktion auf erwartete Modelländerungen geändert werden kann. Beispiel:

// to change to square cell locations, remove the "+ y/2" in the above code

Ich denke, dieser Zweck für Kommentare wird manchmal vernachlässigt.


2
Die Frage fragt nach Beispielen. Könnten Sie ein Beispiel hinzufügen, um diese Antwort nützlicher zu machen?
Bryan Oakley

2
Der erste Codeabschnitt sieht aus wie ein klassisches Beispiel für die Erklärung von "Was" für mich. Nicht, dass es ein schlechter Kommentar wäre, aber ich denke nicht, dass er die Frage des OP beantwortet.

@ Jon: Wenn der Kommentar nicht da wäre, kann der Leser sehen, was passiert, hat aber keine Ahnung warum.
Mike Dunlavey

1
@ MikeDunlavey: Ich bin anderer Meinung. Ich habe immer noch keine Ahnung, warum Sie den nächstgelegenen sechseckigen Zellenstandort suchen. Was ist der Zweck , um diesen Ort zu bekommen? Würde es irgendetwas beeinflussen, wenn ich diese beiden Zeilen löschen würde?

2

Nicht alle meine Kommentare sind vom Typ "Warum", aber viele sind es.
Dies sind Beispiele aus einer (Delphi) -Quelldatei:

// For easier access to the custom properties:

function GetPrivate: Integer;   // It's an integer field in the external program so let's treat it like that here

// The below properties depend on the ones above or are calculated fields.
// They are kept up-to-date in the OnEventModified event of the TTSynchronizerStorage
// or in the ClientDataSet.OnCalcFields of the TcxDBSchedulerStorage.DataSource.DataSet
property IsModified       : Boolean   read GetIsModified   write SetIsModified;
property IsCatTT          : Boolean   read GetIsCatTT      write SetIsCatTT;
property IsSynced         : Boolean   read GetIsSynced     write SetIsSynced;

lLeftPos := pos(' - [',ASubject); // Were subject and [shiftnaam:act,project,cust] concatenated with a dash?

// Things that were added behing the ] we will append to the subject:

// In the storage the custom value must also be set for:
Self.SetCustomFieldValueByname(cCustFldIsCatTT,Result);

// When we show the custom fields in a grid, the Getters are not executed,
// because the DevEx code does not know about our class helpers.
// So we have two keep both properties synchronized ourselves:

// lNewMasterEvent was set to usUpdated, overwrite because we added:
if ARepair then
  lNewMasterEvent.CustUpdateStatus := usRecreated

// The source occurrence date may have bee changed. Using GetOriginalDate we can retrieve the original date,
// then use that for creating a target occurrence (and update its date):

lNewTTOccurrence.CustSyncEntryID := cSyncEntryID0;    // Backward compatibility with old sync methode

// Single event became recurring or vice versa; replace entire event

// In contradiction to CopySingleEventToTimeTell, CopyMasterEventToTimeTell does not have a ANewStatus parameter
// because master events are always added.

Beachten Sie, dass (my) why- Kommentare in der Regel vor dem Code stehen, der sie ausführen soll (daher mit einem Doppelpunkt abschließen).

Ich habe einige Kommentare, die nur erklären, was passiert, z. B. wenn ein Prozess viele Schritte mit einer logischen Gruppierung hat (und der Code nicht überarbeitet wird, um dies automatisch anzuzeigen), werde ich wie folgt kommentieren:

// Step 1. Initialization

1

Ich verstehe das WARUM als den Grund, warum Sie etwas auf eine möglicherweise seltsame oder möglicherweise unlogische Weise tun, aufgrund der gegebenen Umstände, die dies erfordern. Das WIE kann im Code selbst gesehen werden, egal wie seltsam es ist, auch wenn der Code keinen "Sinn" ergibt. Das WAS wird wahrscheinlich am besten zu Beginn der Klassen- / Funktionsdokumentation erzählt. Sie können also das WARUM hinzufügen , in dem Sie alles erklären, was nicht im WIE und WAS enthalten ist, sowie die besonderen Maßnahmen, die Sie aus Gründen ergreifen müssen, die außerhalb Ihrer Kontrolle liegen.

Außerhalb des Landes der Einhörner und Regenbogen ist das natürlich nicht immer der Fall ...

WIE:

foreach($critters as $creature) {
   $creature->dance();
}

WAS:

/* Dancing creatures v1.0
 * 
 * The purpose of this is to make all your critters do the funky dance.
 */

foreach($critters as $creature) {
  $creature->dance();
}

WARUM:

// We had to store the items in an array of objects because of _____ (reason)
foreach($critters as $creature) {
   $creature->dance();
}

5
Wie beantwortet dies die gestellte Frage?
gnat

1
Um OP zu zitieren: "Also, zurück zu der Frage: Wenn Kommentare Ihnen sagen sollten, WARUM, worüber sprechen wir?", Und ich beantwortete diese Frage: Das WARUM, über das gesprochen wird, ist die Begründung für die Existenz des Stück Code gegeben.
Juha Untinen

1
Die Frage fragt speziell einige Male nach Beispielen. Können Sie dieser Antwort ein Beispiel hinzufügen, um sie nützlicher zu machen?
Bryan Oakley

1
Ich denke nicht, dass einer dieser Kommentare wirklich hilfreich ist. Wenn die Signatur Ihrer Funktion war critters.dance(), dann wiederholt der Kommentar nur das Offensichtliche, und "Wir konnten es auf keine andere Weise zum Funktionieren bringen, als wir es versucht haben" ist völlig nicht hilfreich. Wenn Sie "Wir rufen die Methode für jedes Objekt auf" sagen, wiederholen Sie das, was der Code sehr deutlich sagt.
Brendan Long

1

Ich habe gelernt, IMMER Kommentare in C ++ - Headerdateien zu schreiben (da nicht immer klar ist, WAS eine Funktion tut, obwohl der Name einen guten Hinweis gibt), insbesondere, wenn Sie eine API an andere Entwickler weitergeben oder ein Tool für die automatische Verarbeitung wie doxygen verwenden.

Also für mich sieht ein typischer Kommentar so aus

/*** Functionname
/*   What happens here
/*  [in] Params
/*  [out] params
/*** 

Das einzige Mal, dass ich WARUM-Kommentare verwendet habe, sind Dinge, die schwer zu verstehen sind und manchmal sogar für den Programmierer, wie "BERÜHREN SIE DIESES NICHT! Weil ..." oder "PROGRAMM STURZT AB, WENN DIE LINIE GELÖSCHT WIRD ...".

Problemumgehungen, Hacks und seltsames Verhalten qualifizieren sich für WARUM Kriterien in meinen Augen ...

Ein sehr gutes und sogar komisches Beispiel ist diese "Problemumgehung" für einen durcheinandergebrachten Code, der von einer Person namens Richard geschrieben wurde. Eine andere Person hat sie eingepackt und in den Kommentaren erklärt, warum ... https://stackoverflow.com/a/184673/979785

Leider gibt es einige Male, in denen Sie gezwungen sind, Bull **** einzuwickeln, weil Sie das Original nicht berühren können, entweder weil "es immer so war" oder weil Sie keinen Zugang haben oder ... na ja, Sie Ich habe nicht die Zeit, das Original für den Zweck zu reparieren, der sich nicht wirklich für den Overhead qualifiziert.


7
Nur dass es sich bei der Frage um Kommentare handelt , nicht um Dokumentation . Es sind eigentlich verschiedene Dinge (das documentationTag ist bedauerlich, aber immer noch nicht auf die Frage anwendbar).
Thomas

Entschuldigen Sie bitte die Tatsache, dass in meiner Muttersprache der Kommentar und der Dokumentationskommentar synonym verwendet werden, und so habe ich bei dem Tag angenommen, dass dies auch für diese Frage zutrifft. Ist das wirklich ein Grund für eine Ablehnung?
AnyOneElse

2
Die Frage fragt ein paar Mal nach dem Warum von Kommentaren, aber das einzige Beispiel, das Sie einschließen, ist ein Was- Kommentar. Leute, die die Antworten für Beispiele überfliegen, könnten durch Ihr Beispiel irregeführt werden. Können Sie ein Beispiel für einen Warum- Kommentar geben?
Bryan Oakley

obwohl ich sagte, es gibt nur sehr wenige WARUM in meinem Code und ich nannte zwei Beispiele: BEARBEITET ... hier ist ein Link, der definitiv für ein
WARUM

@ AnyOneElse Ich habe nicht abgelehnt. Es war da, bevor ich ankam.
Thomas

0

Code soll Ausführungsplan angeben. Auf diese Weise kann der Programm-Follower (oder der Compiler) herausfinden, was zu tun ist und wie es zu tun ist. Das, was in Schritte unterteilt ist, denen der Programmfolger folgen kann. Die primitiven Schritte sind das Wie.

Die Absicht des Programmierers ist eine andere Sache. In einfachem, klarem und direktem Code ist die Absicht offensichtlich. Jeder einigermaßen geübte menschliche Leser erreicht die Absicht eines Codeblocks, indem er nur den Code liest. Der meiste Code sollte so lauten.

Gelegentlich ist die Beziehung zwischen Absicht und Plan undeutlich. Der Code enthüllt das Was und das Wie, aber nicht das Warum. Dann lohnen sich Kommentare, die die Absicht offenbaren. Die Absicht des Programmierers ist das Warum.


3
Die Frage fragt einige Male nach Beispielen. Können Sie Ihrer Antwort ein Beispiel hinzufügen, um sie nützlicher zu machen?
Bryan Oakley

0

Mit diesem Problem waten Sie jetzt durch gespeicherte Prozeduren und Ansichten gegen ein komplexes und etwas verschlungenes Datenmodell.

Wir haben (zahlreiche) Auswahlen getroffen wie "Fall, wenn x.account nicht null ist und x.address in (Adresse von fedex auswählen), dann x.account sonst y.account end" und die Produktivität wird erwartet, obwohl es keine Zeit gibt all, um den gesamten Quellcode zu lesen . Und dieses Beispiel ist irgendwie sinnvoll, aber immer noch unergründlich.

Die Kommentare erklären, warum wenn in fedex dann x und wenn nicht dann y Licht auf das gesamte System wirft und wenn wir genug von ihnen lesen, fangen wir an, es zu verstehen. Und das ist zu stark vereinfacht, und es gibt Hunderte oder Tausende ähnlicher Aussagen. Mein Herz strahlt warmherzig in Richtung derjenigen, die die Art Dev aus dem Jahr 2007 verwendet haben, die diese Aussagen gemacht haben.

Also ja, komplexe, verschlungene Datenmodelle und haarige Ansichten und gespeicherte Prozeduren mit mehreren gültigen Pfaden, bitte sagen Sie uns aus Liebe zu Gott, warum.


0

Ich habe gerade diesen Kommentar geschrieben. Es ist ein konkretes Beispiel dafür, warum eine Codezeile so ist, wie sie ist, und insbesondere, warum ich sie geändert habe.

Die Methode überprüft gespeicherte Daten und beurteilt, ob sie bis zum heutigen Tag am einen Ende und bis zum Startdatum am anderen Ende vollständig sind.

// In principal, this should be ">=", as we may have data up to the account start
// date but not complete for that day; in practice, 98% of the time if we have
// data for the start date it *is* complete, and requerying it would be a waste
// of time.
while (endDate > accountStartDate)
    ...

Wie Sie wahrscheinlich erraten können, war der Größer-als-Operator größer oder gleich. Der Kommentar erklärt, warum der alte Wert Sinn macht und warum der neue Wert besser ist. Wenn sich jemand dies in Zukunft ansieht, wird er feststellen, dass die Verwendung von ">" kein Versehen ist, sondern eine Optimierung. Sie können es dann je nach Bedarf ändern oder verlassen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.