Quais são os exemplos de comentários que dizem por que, em vez de como ou o quê? [fechadas]

78

Primeiro de tudo, nesta pergunta, eu gostaria de ficar longe da polêmica sobre se o comentário do código fonte é bom ou ruim. Estou apenas tentando entender mais claramente o que as pessoas querem dizer quando falam sobre comentários que dizem por que, o que ou como.

Muitas vezes, vemos diretrizes como "Os comentários devem informar POR QUE; o próprio código deve informar COMO". É fácil concordar com a afirmação em um nível abstrato. No entanto, as pessoas geralmente descartam isso como um dogma e saem da sala sem maiores explicações. Eu já vi isso usado em tantos lugares e contextos diferentes, que parece que as pessoas podem concordar com o slogan, mas parecem estar falando inteiramente de coisas diferentes.

Então, voltando à pergunta: se os comentários devem lhe dizer POR QUE, do que estamos falando? É por esse motivo que esse pedaço de código existe em primeiro lugar? É isso que esse código de peça deve estar fazendo? Eu realmente apreciaria se alguém pudesse dar uma explicação clara e depois adicionar alguns bons exemplos (exemplos ruins não são realmente necessários, mas ficaram à vontade para adicioná-los para contraste).

Há muitas perguntas sobre se os comentários são bons ou ruins, mas ninguém aborda a questão específica de quais são bons exemplos de comentários que dizem POR QUE.

rick
fonte
36
Às vezes, os melhores comentários abordam POR QUE NÃO. Certa vez, encontrei um pedaço complexo de código que parecia ser facilmente simplificado. O comentário explicou por que essa simplificação óbvia não funcionou nessa instância específica (porque o desenvolvedor original já tentou).
precisa saber é o seguinte
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. Se todos fornecerem um exemplo válido, todas serão respostas corretas. O formato deste site é facilitar um processo de perguntas e respostas em que nem todas as respostas são criadas da mesma forma.
David Kaczynski
Bom ponto, @ david-kaczynski. O que você sugere?
Rick
1
De cabeça para baixo, não consigo pensar em uma maneira de formular a pergunta para que um único exemplo ou tática generalizada possa ser a "melhor" resposta. Existe uma parte do chat do p.se: chat.stackexchange.com/rooms/21/the-whiteboard , mas provavelmente haveria um fórum melhor para sua pergunta no momento. Com toda a justiça, parece que sua pergunta está recebendo uma resposta positiva da comunidade aqui, por isso provavelmente não vale a pena se preocupar. O melhor conselho que posso dar para encontrar exemplos de comentários úteis seria navegar nos repositórios públicos populares do git.
precisa

Respostas:

62

O exemplo mais comum e mais distinto são os comentários sobre várias soluções alternativas. Por exemplo, este:

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"

Você certamente encontrará mais exemplos nas fontes Git e Linux; ambos os projetos tentam seguir esta regra.

Também recomendo seguir essa regra ainda mais estritamente com os logs de confirmação . Para comentários de código, pode ser que você corrija o código, mas esqueça de atualizar o comentário. Com a quantidade de código no projeto usual, é garantido que isso aconteça mais cedo ou mais tarde. Por outro lado, o log de confirmação está vinculado a uma alteração específica e pode ser recuperado usando a funcionalidade "anotar" / "culpar" do sistema de controle de versão. Novamente, o Git e o Linux têm alguns bons exemplos.

Veja, por exemplo, este commit . (não copiando aqui, é muito longo). Ele tem quatro parágrafos, ocupando quase toda a página (e um pouco mais do que a tela) descrevendo o que exatamente estava errado e por que estava errado, e continua e modifica todas as seis linhas pendentes. Eles usam comentários como esse para dois propósitos:

  1. Todas as alterações enviadas são revisadas e o log de confirmação é o que deve explicar a alteração ao revisor.
  2. Quando um bug é encontrado, os logs relevantes são recuperados usando "picareta" ou "culpa" para evitar a reversão para um comportamento incorreto anterior.

(note: demorei no máximo 10 minutos para navegar aleatoriamente no repositório git para apresentar esses dois exemplos, por isso seria fácil encontrar mais informações lá)

Jan Hudec
fonte
29

Um comentário que explica por que explica o raciocínio por trás do código - por exemplo:

// 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;
    }
}

Um comentário que explica como explica o que o código faz.

// 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;
    }
}

A diferença é que um mantenedor pode olhar para o primeiro e dizer: "Ah, então isso pode estar desatualizado!" No segundo caso, o referido mantenedor tem um comentário que não diz nada que o código em si não revela (assumindo bons nomes de variáveis).

Aqui está um exemplo da vida real de um comentário do porquê, de algum código do iOS em que trabalhei onde precisávamos obter um endereço de gateway (ou um palpite razoável). Eu poderia ter deixado os comentários que diziam coisas como "Inicializar o soquete de recebimento", mas isso apenas informava ao mantenedor (ou ao futuro) o que estava acontecendo, e não por que eu tinha que fazer esse estranho argumento para obter o endereço de gateway no diretório primeiro lugar.

/*
 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
thegrinner
fonte
4
O primeiro exemplo é excessivamente detalhado e inclui grande parte do "como". Ele deve dizer apenas "Atualize os <doodads> a partir do temp <doodad> para que o usuário possa <foo> com segurança sempre que". O resto é trivial para implicar a partir deste ou do código. Além disso, a "introdução ao conto de fadas" nos quatro primeiros parágrafos do último exemplo é totalmente inútil. Eu deixaria "Viva la kludge!"; é engraçado e está no final. Mas o começo são apenas muitas palavras que precisamos analisar antes de chegar à explicação real.
Jan Hudec 9/08/13
@JanHudec Ajustado conforme o seu feedback. Parece certo?
thegrinner
15
Uma das coisas boas do segundo exemplo é que ele não apenas explica por que o código funciona de uma maneira específica, mas também explica por que outras alternativas razoáveis ​​não foram adotadas. Isso torna o código muito mais sustentável, pois o próximo cara que lê o código e pensa: "Por que não consigo simplesmente analisar a tabela de roteamento?" pode apenas ler o comentário. Além disso, alguém que faz chegar a uma razão legítima para alterar o código será mais confiante de que é seguro fazê-lo. Caso contrário, um mantenedor fica com medo de que qualquer alteração falhe no cenário (desconhecido) que inspirou o kludge.
9133 Brian
18

Gostaria de começar minha resposta com uma citação feita por Jeff Atwood em sua postagem no blog Code Tells You How, Comments Tell You Why :

o melhor tipo de comentário é o que você não precisa

Ele também afirma que:

Você deve primeiro se esforçar para tornar seu código o mais simples possível, sem depender de comentários como uma muleta. Somente no momento em que o código não pode ser mais fácil de entender você deve começar a adicionar comentários.

Concordo totalmente e, neste momento, devo acrescentar que, antes que eu possa começar a simplificar o código o mais simples possível, faço o código funcionar e, em seguida, começo a refatorar. Portanto, durante a primeira execução antes de refatorar, adicione por que os comentários ajudam muito.

Por exemplo, se você usar 3 loops aninhados com tabelas de hash bidimensionais para preencher uma tabela de dias úteis durante a análise de dados, é muito fácil perder o controle do que foi feito por alguém ou até por você mesmo se não for analisado por algumas semanas e refatorar repentinamente.

[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.

A parte superior é um exemplo de como 3 loops aninhados funcionariam antes da refatoração.
Também explicar algumas condições de ramificação pode ajudar a entender o código muito melhor com o que se estava pensando no processo:

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

Mesmo código simples e óbvio funciona bem com comentários. Apenas para tornar as coisas um pouco mais óbvias, mais claras ou fáceis de entender para os colegas e até para você na manutenção de software.

Claro que o xp declara ter um código que é autoexplicativo, mas um comentário de uma linha dói?

Também acho as seguintes regras deste blog muito úteis:

  • Entenda o material antes de escrever
  • Escreva como se seu público fosse da quarta série
  • Pense em como os leitores podem interpretar mal você

Qualquer pessoa que precise retornar ao seu próprio código ou a outra pessoa ou mesmo ao código legado sabe que pode ser uma dor de cabeça. Então, em vez de ser preguiçoso ou tentar ser um super-codificador em não comentar nada ou muito pouco, por que não fazer de si próprio ou de algum pobre coitado, que precisa manter seu código, uma vida futura muito mais fácil, seguindo as regras citadas.

Além disso, muitas decisões de programação feitas são questionadas durante as revisões e nem sempre é claro por que algumas partes foram escritas como eram, mesmo que algumas seções do código sejam vitais para o funcionamento de um programa devido a um erro grave encontrado durante o uso de códigos durante anos. . Portanto, para não aborrecer todos vocês completamente com um tl; dr perto com uma última citação de acmqueue :

A documentação prévia, clara e abrangente é um elemento-chave na criação de software que pode sobreviver e se adaptar. Documentar com padrões elevados diminuirá o tempo de desenvolvimento, resultará em um trabalho melhor e melhorará os resultados. É difícil pedir mais do que isso em qualquer técnica.

Ben McDougall
fonte
8
No seu segundo exemplo, pode-se eliminar completamente os comentários refatorando: actualDayFuture = padIfSingleDigitDate (actualDayFuture); Isso é trivial, mas um exemplo mais robusto se beneficiaria dessa abordagem.
Chris Cudmore
4
Eu teria movido o condicional para o método também. - Novamente, não por algo tão trivial, mas me permite desconsiderar completamente o pensamento sobre a lógica do preenchimento. Não substituiria o seu exemplo original, pois é uma resposta melhor para a pergunta. É mais uma observação lateral, explorando outras alternativas.
22813 Chris Cudmore
1
Anúncio "Certamente, o xp declara ter um código que é autoexplicativo, mas um comentário de uma linha dói?": Os comentários são bons, mas também há o risco de comentar demais. Cada linha de comentário é aquela que alguém pode esquecer de atualizar quando altera o código.
Jan Hudec
1
Uma maneira melhor de dizer isso é "O melhor tipo de comentário é a ausência da necessidade de um comentário". Comentários que não são necessários (mas são escritos de qualquer maneira) não são bons comentários.
Kaz
1
Interessante que o código referenciado int directionCode = (x > oldX) ? DIRECTIONCODE_RIGHT : (x > oldX) ? DIRECTIONCODE_LEFT : DIRECTIONCODE_NONE;esteja com erro. Certamente deveria ser ... (x < oldX) ? DIRECTIONCODE_LEFT : DIRECTIONCODE_NONE;. Boas ideias para comentários - código incorreto.
chux 9/09/15
8

Eu tendem a reduzir os comentários para as referências em que uma determinada funcionalidade / código é explicada mais detalhadamente ou para explicar por que uma certa maneira de programação é escolhida.

Considerando que outros programadores com habilidades semelhantes usam ou leem seu código, é importante comentar se você usa uma maneira diferente do esperado de conseguir algo. Então você pode explicar em um comentário por que você escolhe esse caminho.

Por exemplo, se você pode usar dois sensores diferentes em um dispositivo Android e um deles não atender às suas necessidades, você pode explicar no comentário por que escolheu o outro.

Portanto, o "porquê" deve fundamentar suas escolhas.

Roalt
fonte
5
As referências são um ótimo exemplo. // Este método usa o algoritmo furshclingeheimer para ronsterizar o foobit. Veja http: // ...
Chris Cudmore
8

Os comentários devem informar o que o código não faz, não necessariamente delineado por POR QUÊ , COMO ou O QUÊ . Se você tem bons nomes e possui funções bem delineadas, é bem possível que o código possa lhe dizer exatamente o que está acontecendo. Por exemplo:

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);
}

Este código realmente não precisa de comentários. Os nomes de função e tipo facilitam o entendimento.

Às vezes, no entanto, pode ser difícil ou impossível criar realmente um código fluente como o acima. Por exemplo, o próximo trecho de código é para encontrar um ponto estatisticamente aleatório em uma esfera. A matemática é bastante opaca, portanto, um comentário com um link para a explicação é ajudar a dizer como funciona. Isto pode ser envolto em uma função para contar QUE ele faz sem a necessidade de um comentário se necessário mais de uma vez, caso contrário, o título do link também ajuda nesse departamento.

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));

Outro exemplo de quando os comentários dizem o que o código não explica é para explicar uma decisão. No próximo exemplo, o código não bloqueia uma variável local não thread dentro de um trecho de código encadeado. Há uma razão para isso e o comentário explica POR QUE . Sem o comentário, pode ser considerado um bug, ou simplesmente nem ser notado.

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)
    {
        ...
    }
    ...
}

Talvez possa ser melhorado dizer por que o objeto aleatório não é criado dentro do loop paralelo em primeiro lugar. Se não houver razão, isso também pode fazer com que alguém apareça e perceba que toda a idéia é estúpida e é um bom lugar para refatoração.

Pastilha elástica
fonte
É razoável descrever o código como não necessitando de comentários quando os comentários são precedidos por, WriteTexte não //?
1
Como eu disse na resposta, os comentários são desnecessários mesmo que não haja instruções de impressão, no entanto, eu a editei para remover as instruções de impressão, a fim de tornar o ponto mais claro.
Chewy Gumball
5

Pode ser útil reconhecer diferentes tipos de "porquê" - principalmente:

  • Razões pelas quais o código que parece excessivamente complexo não funcionaria se simplificado (por exemplo, uma digitação aparentemente supérflua pode ser necessária para garantir que o código funcione em alguns casos de canto).

  • Motivos pelos quais alguma operação simples específica que parece perigosa é realmente segura (por exemplo, "Nossa rotina de busca de dados reportará um item fictício do item após o último como sendo menor do que qualquer outra coisa, e o item depois como sendo maior; qualquer item que deva classificar antes de outro, em uma sequência ascendente ou descendente consistente, terá pelo menos mais um item (possivelmente falso) seguindo-o ").

Em muitos casos, um comentário do segundo tipo em uma parte do código pode "corresponder" a um comentário do primeiro tipo em outra (por exemplo, "Embora pareça que essa sequência de operações possa ser simplificada, a rotina Fitz se baseia em o Wongle não será Woozled até depois que o Bandersnatch tenha sido tocado. ")

supercat
fonte
2

Não se esqueça, se você está escrevendo um programa, não está apenas digitando coisas aleatoriamente, mas sim porque tem um modelo do que deseja , seja em um documento formal ou apenas na sua cabeça. Coisas na sua cabeça são tão reais quanto software / dados em um computador (e com a mesma probabilidade de conter bugs).

Alguém que lê o seu código pode não ter esse modelo na cabeça; portanto, os comentários podem servir para dizer qual era o modelo e como o código está relacionado a ele. Eu acho que é isso que significa "por que". Certamente, é bom tornar o código em si o mais auto-explicativo possível, mas isso nem sempre é bom o suficiente. Exemplo:

// 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);

Além disso, o modelo muda com o tempo e essas alterações precisam ser transferidas para o código. Portanto, os comentários precisam não apenas dizer "por que" algo está no código, mas também tão importante quanto alterá-lo em resposta a alterações antecipadas do modelo. Exemplo:

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

Eu acho que esse propósito para comentários às vezes é negligenciado.

Mike Dunlavey
fonte
2
A questão está pedindo exemplos. Você poderia adicionar um exemplo para tornar esta resposta mais útil?
Bryan Oakley
2
O primeiro pedaço de código parece um exemplo clássico de explicar "o quê" para mim. Não que seja um comentário ruim, mas acho que não responde à pergunta do OP.
@ Jon: Se o comentário não estava lá, o leitor pode ver o que está acontecendo, mas não tem idéia do porquê.
precisa saber é o seguinte
1
@ MikeDunlavey: Eu discordo. Ainda não tenho ideia - por que você deseja a localização mais próxima da célula hexagonal? Qual é o objetivo de obter este local? Isso afetaria alguma coisa se eu excluísse essas duas linhas?
2

Nem todos os meus comentários são do tipo 'por que', mas muitos são.
Estes são exemplos de um arquivo de origem (Delphi):

// 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.

Observe que (meu) por que os comentários geralmente precedem o código que o fará (portanto, termina com dois pontos).

Eu tenho alguns comentários explicando apenas o que está acontecendo, por exemplo, quando um processo tem muitas etapas que possuem um agrupamento lógico (e o código não é refatorado para mostrar isso automaticamente), comentarei como:

// Step 1. Initialization
Jan Doggen
fonte
1

Entendo o porquê como a razão pela qual você faz algo de uma maneira possivelmente estranha ou talvez ilógica, devido às circunstâncias que exigem que isso seja feito. O HOW pode ser visto no próprio código, por mais estranho que seja, mesmo que o código não faça "sentido". O QUE é provavelmente melhor dito no início da documentação de classe / função. Isso deixa você adicionando o PORQUÊ , onde você explica tudo o que não está incluído no COMO e O QUE, e as maneiras peculiares que você precisa seguir devido a razões fora de seu controle.

Claro que nem sempre é o caso, fora da terra dos unicórnios e do arco-íris ...

QUÃO:

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

O QUE:

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

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

PORQUE:

// We had to store the items in an array of objects because of _____ (reason)
foreach($critters as $creature) {
   $creature->dance();
}
Juha Untinen
fonte
5
Como isso responde à pergunta?
mosquito
1
Para citar OP: "Então, voltando à pergunta: se os comentários devem lhe dizer POR QUE, do que estamos falando?", E eu respondi a essa pergunta: o POR QUE se fala é o raciocínio para a existência do dado pedaço de código.
precisa saber é o seguinte
1
A pergunta pede especificamente exemplos algumas vezes. Você poderia adicionar um exemplo a esta resposta para torná-la mais útil?
Bryan Oakley
1
Não acho que nenhum desses comentários seja realmente útil. Se a assinatura da sua função foi critters.dance(), o comentário apenas repete o óbvio, e "Não conseguimos fazer com que funcionasse de qualquer outra maneira que tentamos" é completamente inútil. Além disso, dizer "chamaremos o método para cada objeto" está repetindo o que o código diz claramente.
Reponha Monica
1

Eu aprendi a escrever SEMPRE comentários em arquivos de cabeçalho C ++ (já que nem sempre é claro o que uma função faz, mesmo que o nome dê uma boa dica), especialmente se você passar uma API para outros desenvolvedores ou usar uma ferramenta para autodoc como doxygen.

Então, para mim, um comentário típico parece algo como

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

A única vez em que usei POR QUE os comentários são coisas difíceis de entender e, às vezes, até para o programador, como "NÃO TOQUE NESTE! Porque ..." ou "O PROGRAMA VAI COLOCAR SE A LINHA É EXCLUÍDA ..."

Soluções alternativas, hacks e comportamento estranho se qualificam para os critérios WHY aos meus olhos ...

Um exemplo muito bom e até hilário é essa "solução alternativa" para algum código confuso escrito por uma pessoa chamada Richard, alguém o envolveu e explicou por que nos comentários ... https://stackoverflow.com/a/184673/979785

Infelizmente, existem algumas vezes em que você é forçado a quebrar a merda porque não pode tocar no original, ou porque "sempre foi assim" ou você não tem acesso ou ... bem, você não tem tempo para consertar o original para a finalidade realmente não se qualifica para a sobrecarga.

Alguém mais
fonte
7
Exceto que a pergunta é sobre comentários , não documentação . Na verdade, são coisas diferentes (a documentationtag é lamentável, mas ainda não se aplica à pergunta).
Thomas
Bem, desculpe o fato de que, no meu idioma nativo, o comentário e o comentário da documentação são usados ​​de forma intercambiável e, portanto, com a tag, presumi que fosse aplicável a essa pergunta também. Isso é realmente um motivo para votar?
AnyOneElse
2
A pergunta pede algumas vezes exemplos de por que comentários, mas o único exemplo que você inclui é o que comenta. As pessoas que examinam as respostas dos exemplos podem ser enganadas pelo seu exemplo. Você pode dar um exemplo de um porquê comentar?
Bryan Oakley
embora eu disse que há muito poucas porquês no meu código, e eu nomeou dois exemplos: Editado ... aqui está um link, que definitivamente se qualifica para um PORQUE
AnyOneElse
@AnyOneElse Eu não diminuí a votação. Estava lá antes de eu chegar.
Thomas
0

O código deve especificar o plano de execução. Dessa forma, o seguidor do programa (ou o compilador) pode descobrir o que fazer e como fazê-lo. O que é dividido em etapas que o seguidor do programa pode seguir. Os passos primitivos são o como.

A intenção do codificador é outra questão. Em um código simples, claro e direto, a intenção é óbvia. Qualquer leitor humano razoavelmente proficiente chegará à intenção de um bloco de código, apenas lendo o código. A maioria dos códigos deve ser assim.

Ocasionalmente, a relação entre intenção e plano é obscura. O código revela o quê e como, mas não o porquê. É quando os comentários que revelam a intenção valem a pena. A intenção do programador é o porquê.

Walter Mitty
fonte
3
A pergunta pede algumas vezes exemplos. Você pode adicionar um exemplo à sua resposta para torná-la mais útil?
Bryan Oakley
0

Ter esse problema no momento percorrendo procedimentos armazenados e visualizações em um modelo de dados complexo e um tanto complicado.

Criamos (numerosas) seleções como "Caso em que x.account não é nulo e x.address in (selecione o endereço do fedex) e x.account else y.ccount end" e a produtividade é esperada, embora não haja tempo em tudo para ler todo o código fonte. E esse exemplo meio que faz sentido, mas ainda é inescrutável.

Os comentários explicando por que, se no fedex, x e se não, y - lança luz sobre todo o sistema e, quando lemos o suficiente, começamos a obtê-lo. E isso é simplificado e existem centenas ou milhares de declarações semelhantes. Meu coração brilha calorosamente em relação a quem foi o tipo dev de 2007 que colocou aqueles por que.

Então sim, modelos de dados complexos e complicados, veiws peludos e procedimento armazenado com vários caminhos com nome válido, por favor, pelo amor de D'us, diga-nos o porquê.

naftalimich
fonte
0

Acabei de escrever este comentário; é um exemplo concreto de explicar por que uma linha de código é o que é e, em particular, por que eu a mudei.

O método examina os dados armazenados e avalia se eles estão completos até os dias atuais, por um lado, e até a data de início do outro lado.

// 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)
    ...

Como você provavelmente pode adivinhar, o operador maior que tinha sido maior ou igual. O comentário explica por que o valor antigo faz sentido e por que o novo valor é melhor. Se alguém olhar para isso no futuro, verá que o uso de ">" não é uma supervisão, mas uma otimização. Eles podem alterá-lo ou deixá-lo, com base na necessidade naquele momento.


fonte