Czy istnieje metoda odróżnienia komentarzy informacyjnych od skomentowanego kodu?

36

W trakcie programowania pojawi się kilka komentarzy wyjaśniających kod i kilka komentarzy usuwających kod:

// A concise description 
const a = Boolean(obj);
//b = false;

Czy istnieje dobra metoda szybkiego parsowania, która jest która?

Bawiłem się przy użyciu 3 /i /** */do opisowych komentarzy.

Użyłem również wtyczki VSCode do wyróżnienia //TODO:i//FIXME:

As
źródło
2
Jako notatkę, ///a /** ... */komentarze są także wykorzystywane przez niektórych wytwórców dokumentacji, takich jak Doxygen lub JSDoc. Jeśli użyjesz ich lub podobnych narzędzi, możesz nie być w stanie użyć tego rodzaju komentarza do opisowych komentarzy, które nie są przeznaczone do dokumentacji.
Justin Time 2 Przywróć Monikę
1
W javascript większość linii kodu prawdopodobnie zakończy się średnikiem. Chyba że twoje komentarze tak robią, wydaje się to dość proste i możesz napisać skrypt, aby to łatwo sprawdzić;
Artemis Fowl

Odpowiedzi:

187

Jest na to bardzo proste rozwiązanie: usuń skomentowany kod.

Naprawdę istnieją tylko dwa dobre powody, aby skomentować kod: przetestować coś / naprawić lub zapisać kod, którego możesz użyć później. Jeśli testujesz lub naprawiasz coś, usuń skomentowany kod, jak tylko skończysz test lub poprawkę. Jeśli zapisujesz kod, którego możesz użyć później, uczyń go kodem pierwszej klasy i umieść go gdzieś, na przykład w bibliotece, w której można go dobrze wykorzystać.

Robert Harvey
źródło
108
Ponadto, jeśli kod został zarejestrowany: wystarczy go usunąć. Jeśli kiedykolwiek będziesz go potrzebować, kontrola źródła cię
zapewniła
38
Po usunięciu kodu nikt nie zauważa, że ​​on kiedykolwiek istniał. To utrudnia powrót do zdrowia. Pozostawienie skomentowanego kodu ma wartość, szczególnie jeśli wydaje się prawdopodobne, że zostanie on użyty w przyszłości.
usr
76
@usr: Po usunięciu kodu nikt nie zauważa, że ​​on kiedykolwiek istniał - i według mojego doświadczenia, w 99% wszystkich rzeczywistych przypadków jest to słuszne. W 1% może występować pewna wartość w komentarzach, jednak jeśli skomentowany kod pozostanie przez kilka tygodni lub miesięcy (lub dłużej), szanse są duże, że nawet się nie skompiluje z powodu refaktoryzacji aktywnego linie kodu. Argument „wartość umowna dla przyszłych zastosowań” jest często używany jako niewłaściwa wymówka dla osób, które mają emocjonalny problem z oderwaniem rzeczy od bazy kodu, na którą zainwestowały kilka godzin pracy mózgu.
Doc Brown
21
Nigdy nie popełniam komentarza bez dodatkowych wyjaśnień. Są rzadkie sytuacje, w których możesz chcieć przywrócić kod w najbliższym czasie, ale każdy z nich jest wyjątkowy i wymaga wyjaśnienia dla przyszłych programistów (lub przyszłych Ciebie). 90% moich komentarzy to „Usunięte, ponieważ wydaje się, że nie jest używane. Usuń po lis 2021, jeśli nie ma żadnych problemów”
James Beninger
30
Mój kolega powiedział kiedyś: „Był tu kod, który zrobił X, ale go usunąłem”, kiedy na razie usunęliśmy jakąś funkcję. To działało naprawdę dobrze; wiedziałeś, że jest to historia źródłowa tego pliku, ale nie przeszkadzało ci to.
Erik
45

Dodając do doskonałej odpowiedzi @ RobertHarvey, uważam, że istnieje tylko jeden uzasadniony powód, dla którego kiedykolwiek spotkałem się z zapisaniem skomentowanego kodu w kontroli źródła, nawet tymczasowo: w przypadku nieoczywistego kodu zastępczego, który z jakiegoś powodu nie powinien lub nie może zostać użyty . Nawet wtedy większość komentarza powinna być wyjaśnieniem, a nie kodem zastępczym. Może to być błąd lub funkcja języka, który nie jest jeszcze uważany za stabilny. Może to wyglądać mniej więcej tak:

# TODO: Replace with `foo = frobnicate(bar)` once <link.to/bug> is fixed
foo = [some complex workaround]

W tym przypadku praca została już wykonana, ale nie możesz jeszcze z niej skorzystać, więc usunięcie jej oznacza, że ​​ktoś będzie musiał ją później odkryć. To samo dotyczy rozwiązań nieoptymalnych, które mogą wydawać się lepsze na pierwszy rzut oka lub świadomych kompromisów z podobnymi rozwiązaniami .

Uwaga: nie zaśmiecaj swojego kodu alternatywnymi rozwiązaniami. Każde zadanie można wykonać na nieskończenie wiele różnych sposobów, a eksplorowanie tej przestrzeni przez długi czas przy każdej zmianie nie jest opłacalne. Recenzje kodu mogą być dobrym miejscem do odkrycia takich brakujących komentarzy, gdy twój kolega sugeruje ulepszenie, które już odkryłeś, że jest nieoptymalne.

l0b0
źródło
2
Drugą stroną tego jest to, że czasami musisz wyjaśnić, dlaczego nie używasz frobnicate(bar), aby nikt nie przyszedł i nie próbował naprawić „nieeleganckiego” kodu. Więc pokazujesz im, że wiesz, że w idealnym świecie ta frobnicatefunkcja byłaby właściwą drogą, ale wiesz z bolesnego doświadczenia, że ​​to nie działa poprawnie. Może nie być żadnych oczekiwań, że strona trzecia nawet uzna to za błąd, a tym bardziej nie warto go naprawiać; nadal musisz zostawić komentarz przyszłym programistom (w tym sobie) na temat tego, dlaczego nie przyjąłeś oczywistego podejścia.
Monty Harder
3
Powiązaną sytuacją jest to, że mogą istnieć dwa sposoby zrobienia czegoś, z których jeden przetwarza prawidłowe dane znacznie szybciej niż drugi, a jeden z nich oferuje bardziej przydatną diagnostykę, jeśli z jakiegokolwiek powodu otrzyma nieprawidłowe dane. Jeśli program jest częścią procesu, który powinien podawać mu tylko te dane, które są „gwarantowane”, że są prawidłowe, ale coś w tym procesie nie działa poprawnie, posiadanie wolniejszej wersji, ale oferującej lepszą diagnostykę, może sprawić, że o wiele łatwiej ustalić, co się dzieje.
supercat
20

Hmm, przeczytałem to pytanie nieco inaczej niż Robert, który poprawnie twierdzi, że skomentowany kod powinien zostać usunięty.

Jeśli jednak szukasz konwencji oznaczania kodu do późniejszego usunięcia, moim ulubionym jest:

//b = false; //TODO: remove

//TODO:Komentarze flag IDE lub można się ich nauczyć. Jeśli nie, zwykle jest to ciąg do przeszukiwania. Najlepiej postępować zgodnie z konwencją ustanowioną przez sklep, ponieważ można to zrobić na kilka sposobów. Każda baza kodu powinna robić to w jeden sposób. Umożliwia wyszukiwanie.

szybko parsuj który jest który?

Bez tego znaku zautomatyzowanym sposobem na to jest kompilator. Jeśli usunięcie komentarza powoduje powstanie kodu, który się kompiluje, kod musi zostać skomentowany. Pisanie wtyczki IDE, która sprawdza, co nie byłoby trudne. Ale pozostawi błędny kod z komentarzem.

Dlatego lepiej po prostu oznaczyć kod z komentarzem jako kod w momencie, gdy go skomentujesz. Dzięki temu możesz pracować nieniszcząco, jednocześnie decydując, czy naprawdę chcesz tego odejść. Ponieważ wszyscy zostają nam przerwani i jesteśmy nieco zapomniani, nie zdziw się, jeśli niektóre linie zostaną sprawdzone w tym stanie. Jeśli tak, to fajnie, że są przynajmniej wyraźnie oznaczone i można je wyszukiwać. W przeszłości pomogły mi makra klawiaturowe. Trudno jest w tym przerwać, jeśli możesz to zrobić jednym naciśnięciem klawisza.

Możesz to zrobić, jeśli chodzi o zapisywanie znaku w ciągłych testach integracyjnych. Ups, próbuję ponownie sprawdzić w znakomitych TODO.

candied_orange
źródło
Zamiast sprawdzać, czy komentarze kompilują się, by oznaczyć je jako kod, możesz uruchomić komentarze przez procesor języka naturalnego i oznaczyć te, które parsują jako zdanie lub frazę w języku, w którym mówi Twój zespół.
TheHansinator,
3
@ TheHansinator, który brzmi dobrze, ale moje doświadczenia z automatycznymi poprawnymi relacjami z żargonem kodera powodują, że jestem ostrożny.
candied_orange
Wyobrażam sobie, że NLP używane do analizowania komentarzy do kodu byłoby znacznie lepsze niż NLP, które obsługuje autokorekty, po prostu dlatego, że komputer ma całe zdanie do pracy i nie próbuje poprawiać błędów ortograficznych. Nie wspominając już o tym, że fałszywy negatyw również jest lepszy - tak długo, jak człowiek jest w stanie przejrzeć komentarz przed usunięciem, może po prostu przepisać komentarz, w przeciwieństwie do braku powiadomienia o bezużytecznym gobbledygook.
TheHansinator
3
parsowanie wrt: double buffer (flip on)-> prototyp C czy ultra-krótki angielski? nie można powiedzieć bez kontekstu, niepoprawna cała konstrukcja w żadnym języku. Niektóre fałszywe pozytywy i negatywy są nieuniknione, gdy komentarze z natury nie ograniczają formy treści w obu kierunkach.
Leushenko
8

Używam dyrektyw preprocesora do usuwania kodu, a nie komentarzy w ogóle:

//comment
active_code();
#if FALSE
inactive_code();
#endif

To sprawia, że ​​bardzo łatwo jest szukać, a mój wyróżnik składni traktuje to jako komentarz. Mogę nawet zwinąć go w jedną linię:#if FALSE(...)

Możesz rozwinąć ten pomysł, aby mieć kilka opcji:

#if OPTION == 0
code_for_option_0();
#elif OPTION == 1
code_for_option_1();
#else
code_for_all_other_options();
#endif

I sprawdzanie błędów w czasie kompilacji:

#if FOO >= 5
#error FOO should be less than 5!
#endif

Oczywiście nie chcesz przesadzać, albo trudno jest powiedzieć, co się kompiluje, a co nie. Ale masz pomysł, i tak samo jest w przypadku skomentowanego kodu ... pod warunkiem, że używasz go tylko statycznie. Jeśli twoje warunki są dynamiczne, jest gorzej.


Aby ustalić, która jest w istniejącej bazie kodu, która w ogóle nie brała pod uwagę tego problemu, nie sądzę, że istnieje uniwersalne rozwiązanie. Musisz sam znaleźć wzorce i prawdopodobnie kodować wyrażenie regularne, aby je znaleźć.

AaronD
źródło
Do czego na świecie byłoby to dobre? Czy potrzebujesz skompilować wiele wersji?
Tvde1
@ Tvde1 To jedna z możliwości i potencjalny koszmar, jeśli nie poradzisz sobie z tym zbyt dobrze. Ale alternatywa jest prawdopodobnie gorsza. Jeśli masz wiele kopii prawie tego samego kodu, po jednym dla każdej odmiany wspólnego motywu, musisz zachować je osobno i zsynchronizować.
AaronD
Można to zrobić na kilka sposobów, ale wszystkie różnią się zarówno złożonym problemem konfiguracyjnym, jak i problemem niezależnej kopii: Czy jesteś pewien, że poprawka dotarła do wszystkich niezależnych kopii? Co się stanie, jeśli nie, i zostanie dodana inna funkcja, która jest następnie łamana przez poprawkę błędu znaną wcześniej, ale do tej pory nie przeniesioną?
AaronD
3
Który działa tylko wtedy, gdy mają do wstępnego przetwarzania kroku jak C. pytanie dotyczy javascript. Możesz wykonać wstępne przetwarzanie, ale rozszerzy ono możliwości systemu kompilacji i jest również niestandardowe. Jeśli nie masz systemu kompilacji lub system kompilacji w ogóle nie obsługuje analizowania i wykonywania kodu, nie będziesz w stanie zaimplementować tego rozwiązania. Wreszcie, nawet nie rozwiązuje pytania - skomentowany kod nie jest ściśle równoważny kodowi, który jest aktywowany warunkowo. Może to być pozostałość, której nie należy włączać.
VLAZ
Aktywacja warunkowa jest jedynie rozszerzeniem odpowiedzi, a nie samą odpowiedzią. W przeciwnym razie edytowałbym go, aby uwzględnić komentarze, które jeszcze go rozszerzają.
AaronD
4

Zgadzam się z odpowiedzią stwierdzającą, że stary kod powinien zostać usunięty, a nie skomentowany tam, gdzie to możliwe, jednak przestrzegałem konwencji w tych kilku przypadkach, w których potrzebny jest kod z komentarzem.

(Moja podstawa to C #, ale można to zastosować w dowolnym języku składni C, np. Java)

// An explanatory comment has a space between the comment marker and the content.

// The following lines are commented out code so do not have the space (except where indented).
//var a = something();
//if(a==2) {
//   doSomethingElse();
//}
IanF1
źródło
2
Zależy to całkowicie od stylu: kiedy komentuję kod, generalnie dodam go //do pierwszej kolumny, a ponieważ praktycznie cały kod jest wcięty, praktycznie zawsze jest tak, że komentarz zaczyna się od niektórych zakładek. Normalne komentarze nie otrzymują ode mnie wiodącej przestrzeni, chyba że w pobliżu są już inne komentarze z wiodącą przestrzenią. Tak więc twoja metoda zawiodłaby śmiertelnie na komentarzach, które stworzyłem, a każda metoda zaprojektowana w celu rozpoznania moich wzorców komentarzy zawiodłaby na twojej.
cmaster
@cmaster Ah Rozumiem, myślę, że źle zrozumiałem pytanie. Podałem prosty sposób formatowania komentarzy w taki sposób, aby można je było łatwo przeanalizować pod kątem typu, a nie o to proszono.
IanF1,
2

Wciąż interpretuję to pytanie, myśląc, że chcesz znaleźć skomentowany kod.

Kod w stylu C musi zawierać w sobie średniki, podczas gdy w komentarzach raczej nie będzie w nich średników. W przypadku kodu z komentarzem w jednym wierszu można użyć tego wyrażenia regularnego:

\s*\/\/[\s\S]*;

Może to być kod skomentowany z wielu wierszy

\/\*[^\;]*;[^\;]*\*\/

Uwaga: Visual Studio jest nieco osobliwy w przypadku podziałów linii w wyrażeniach regularnych, nie liczą się one jako białe znaki, musisz podać wyraźne \ n.

Martin Maat
źródło
2

Jeśli używasz edytora z kompilatorem działającym w tle (takim jak Xcode i Clang), możesz po prostu spróbować skompilować tekst komentarza. Na przykład „zwięzły opis” podaje błędy, „b = fałsz;” nie. Możesz wtedy użyć innego podświetlenia składni.

Prostszą metodą byłaby wtyczka IDE, która korzysta z niektórych heurystyk, takich jak wiele słów w wierszu innych niż słowa kluczowe, które wskazują na komentarze, dopasowane kręcone, punktowane do kodu itp.

gnasher729
źródło
1

Inne odpowiedzi dotyczyły odmian tematu „nie komentuj kodu”. Ale czasami nadal chcesz go mieć w celach informacyjnych.

Jeśli naprawdę potrzebujesz kodu, aby pozostać w pobliżu, lepszym rozwiązaniem jest otoczyć go kodem „#if 0 ... #endif”, najlepiej z komentarzem wyjaśniającym dlaczego. Jest to zalecana strategia różnych standardów kodowania, w tym MISRA.

Graham
źródło
-3

Proste, przynajmniej dla mnie - i w C / C ++. Komentarze zawarte w / * * / mają charakter informacyjny. Kod testowy, który jest tymczasowo usuwany, jest komentowany za pomocą wiodącego //.

I jest dobry powód, aby zostawić kod testowy w pliku, ale skomentował, przynajmniej w rodzaju pracy, którą wykonuję. Wcześniej czy później ktoś będzie chciał wprowadzić zmiany, które będą wymagać tego kodu. Odkomentowanie bloku wymaga jednego polecenia edytora, podobnie jak ponowne komentowanie go po zakończeniu.

jamesqf
źródło
Istnieje również #ifdef __DEBUG ... #endifdowolna niestandardowa definicja, której chcesz użyć. __DEBUGjest miło, ponieważ często wystarczy zmienić konfigurację projektu, aby go uzyskać. Ale większość IDE pozwala również definiować własne konfiguracje, które mogą dać ci wszystko w tym miejscu.
AaronD
Co rozumiesz przez „kod testowy”? Testy jednostkowe? Nie należy ich w ogóle komentować, ale przechowywać w pakiecie testowym i uruchamiać tak często, jak to możliwe, niezależnie od tego, czy ktoś uważa to za konieczne. Jasne, łatwo jest ponownie skomentować fragment kodu, ale jeszcze łatwiej jest w ogóle nie robić nic i mieć już
gotowy
1
Argh, nie rób tego. Komentowanie kodu „przetestować coś” będzie działało idealnie 99 na 100 razy ... aw jednym przypadku zapomnisz go usunąć (jeśli nie jest już potrzebny) lub - co gorsza - zapomnisz odkomentować ( jeśli jest to potrzebne), a rzeczy mogą stać się brzydkie.
CharonX
@leftaroundabout: Nie, mam na myśli takie rzeczy, jak instrukcje printf wprowadzone w celu sprawdzenia wartości.
jamesqf
@ jamesqf nigdy nie powinieneś potrzebować tego rodzaju rzeczy, po to jest debugger. Ale nawet jeśli używasz printf/ coutlub podobnego do poprawnego napisania nowo napisanego kodu (co muszę przyznać, że robiłem to w przeszłości), pozostawienie ich tam naprawdę nie jest zbyt skuteczne. Jeśli ktoś chce wprowadzić zmiany i wie, o których zmiennych potrzebuje informacji, szybko i łatwo napisać od printfnowa, natomiast jeśli ten deweloper nie wie, co jest potrzebne i po prostu cofnie komentarz wszystkich tych printfstwierdzeń, wówczas ogromny pokos tekstu w terminal prawdopodobnie też im nie pomoże.
leftaroundabout