You are viewing an old revision of this post, from October 3, 2023 @ 20:49:54. See below for differences between this version and the current revision.
Tradicionalmente, considera-se uma boa prática comentar o código. Há algum tempo, tem-se revisto este conceito. Na Liferay, por exemplo, seguimos uma política de não comentar código. Pessoalmente, sou um entusiasta desta filosofia. Mas não quero apresentar ou defender esta estratégia: há muito material bom sobre isto. Quero discutir uma questão em aberto.
Quem comenta quer transmitir alguma informação importante. Que informação é essa? E, mais importante ainda, onde podemos registrá-la? Vejamos algumas alternativas.
O que essas linhas fazem?
Os nomes de funções são excelentes para explicar o que o código faz. Se um bloco de código precisa de um comentário, considere extraí-lo para uma função ou classe. O nome da entidade já esclarecerá seu propósito.
Observe, por exemplo, as linhas abaixo, retiradas desta classe de testes:
Assert.assertNotNull(recurrence);
Assert.assertNull(recurrence.getUntilJCalendar());
Assert.assertEquals(0, recurrence.getCount());
Code language: CSS (css)
Essas linhas verificam se a RRule de um evento tem certas propriedades: ela deve existir, ter um “until” Calendar
nulo e uma contagem de zero.
Os conceitos são complexos; eu mesmo me confundiria ao reler estes asserts. Um comentário poderia explicá-los. Mas este commit já esclareceu tudo ao mover essas linhas para um método e invocá-lo:
assertRepeatsForever(recurrence);
Aquelas asserções verificavam se o evento se repete eternamente! Nenhum comentário foi necessário — felizmente, pois estes asserts estavam em vários testes.
O que está acontecendo?
Se o comentário iria explicar algo relevante em tempo de execução, considere transformá-lo em uma mensagem de log! Note o exempo abaixo.
if (Validator.isBlank(serviceAccountKey)) {
// If no credentials are set for GCS Store, the library will
// Application Default Credentials.
_googleCredentials =
ServiceAccountCredentials.getApplicationDefault();
}
else {
_googleCredentials = ServiceAccountCredentials.fromStream(
new ByteArrayInputStream(serviceAccountKey.getBytes()));
}
Code language: JavaScript (javascript)
Este comentário pode relevante para quem lê o código. Contudo, seria crucial para alguém investigando um problema de autenticação. Por isso, na prática, escolhi logar uma mensagem:
if (Validator.isBlank(serviceAccountKey)) {
if (_log.isInfoEnabled()) {
_log.info(
"No credentials set for GCS Store. Library will use " +
"Application Default Credentials.");
}
_googleCredentials =
ServiceAccountCredentials.getApplicationDefault();
}
else {
_googleCredentials = ServiceAccountCredentials.fromStream(
new ByteArrayInputStream(serviceAccountKey.getBytes()));
}
Code language: JavaScript (javascript)
Por que estão aqui?
Comentários para explicar por que algumas linhas estão ali também são comuns. Um local melhor para compartilhar essas informações são as mensagens de commits.
Estes dias, por exemplo, me pediram para ajudar com um código em que trabalhei anos atrás. Lendo uma JSP — lembre-se, anos atrás — eu encontrei essas linhas:
<liferay-portlet:renderURL portletName="<%= KaleoDesignerPortletKeys.KALEO_DESIGNER %>" var="viewURL">
<portlet:param name="mvcPath" value="/designer/view_kaleo_definition_version.jsp" />
<portlet:param name="redirect" value="<%= currentURL %>" />
<portlet:param name="name" value="<%= kaleoDefinitionVersion.getName() %>" />
<portlet:param name="draftVersion" value="<%= kaleoDefinitionVersion.getVersion() %>" />
</liferay-portlet:renderURL>
Code language: HTML, XML (xml)
Esta tag está gerando uma URL para ser utilizada em outro lugar. Mas meus olhos treinados acharam estranho aquele parâmetro portletName
. Este valor costumar ser definido automaticamente.
Um git blame
esclareceu tudo, quando encontrei este commit. A mensagem é clara:
LPS-74977 / LPS-73731 By making the render URL explicitly use the Kaleo Designer name, it will be valid when rendered in another portlet.
Entendi! Este código provavelmente vai ser invocado por algum outro portlet. Neste caso, o valor seria automaticamente setado pela outra aplicação, e por alguma razão queremos evitar isso.
(Por esta razão, aliás, prefiro commits pequenos: eles facilitam descobrir a razão de trechos de código bem específicos. É como se todas as linhas de código tivessem um comentário! Não é uma posição unânime, porém: há quem prefira commits maiores.)
A razão da linha foi esclarecida. Mas por que ela pode ser invocada de outra aplicação? Isto não é usual…
Por que esta mudança foi feita?
Um código bem escrito explica como algo foi implementado. A mensagem de commit esclarece o porquê, mas em um contexto local. Como explicar a motivação mais ampla por trás de um código sem recorrer a comentários?
Os tíquetes do issue tracker são excelentes para isto. Normalmente escritos para guiar o desenvolvimento, esses documentos ajudam demais na interpretação do código. Se adicionarmos a chave do tíquete à mensagem de commit, podemos rastrear as razões.
Voltando ao exemplo acima. Descobrimos que uma linha permite usar o mesmo código em vários portlets. Mas isso raramente é necessário. Por que precisamos reutilizar o código neste caso? Por sorte, a mensagem menciona dois tíquetes. Fui verificar o mais antigo; cheguei a LPSA-64324:
[Information Architecture] EE – As a portal admin, I would like to access all workflow portlets from the control panel section under the same tab.
O título já ajuda, e o texto esclarece de vez. Por razões de usabilidade, três aplicações diferentes passaram a aparecer em abas de um mesmo portlet. Faz todo sentido!
Os comentários que a gente gosta
É importante destacar que tentamos evitar comentários desorganizados, que se entrelaçam no código e tentam explicar trechos difíceis de entender. Há vários comentários, frequentemente com formatos padronizados, que não atrapalham a leitura. Um exemplo óbvio são os cabeçalhos de copyright.
Outra maneira de usar comentários efetivamente é a programação letrada. Neste estilo de programação, os comentários são a estrela do show: o código-fonte contem mais prosa do que código executável. Isto é útil quando explicar o algoritmo é mais importante do que lê-lo, como em pesquisas acadêmicas e análise de dados. Não por acaso, é o paradigma de ferramentas populares como Jupyter Notebook e Quarto.
Mais relevante ainda, ferramentas como Javadoc, JSDoc, Doxygen etc. leem comentários em um formato específico para gerar documentação. Estes comentários não afetam a legibilidade. Pelo contrário: javadocs são ótimos para explicar como usar estas entidades. Combinados com ferramentas como meu querido Doctest, temos até garantias de acurácia e atualidade!
Um mundo de possibilidades
Esses são apenas alguns exemplos de alternativas aos comentários. Há muitas outras opções, como wikis, blogs. Já encontrei a explicação para um código que escrevi no Stack Overflow! Podemos pensar em ainda mais soluções para atender a diferentes necessidades. O ponto principal é que, tendo estas ferramentas à nossa disposição, adicionar comentários diretamente ao código torna-se desnecessário.
Naturalmente, evitar comentários é apenas uma das formas para se escrever código legível. Comentários não são proibidos; de fato, há estratégias que podem torná-los eficazes. No entanto, na minha experiência, comentar indisciplinadamente leva a piores resultados, e essas técnicas ajudam a documentar informações importantes que não cabem diretamente no código.
Você é um adepto da estratégia “sem comentários”? Se sim, que outros meios você usa para transmitir infirmações? Se não, como você faz para ter comentários efetivos? Que tipo de comentário você não vê sendo substituído por essas abordagens? Adoraria escutar suas opiniões.
Post Revisions:
- October 3, 2023 @ 20:51:40 [Current Revision] by brandizzi
- October 3, 2023 @ 20:51:40 by brandizzi
- October 3, 2023 @ 20:50:26 by brandizzi
- October 3, 2023 @ 20:49:54 by brandizzi
- October 3, 2023 @ 20:49:34 by brandizzi
Changes:
October 3, 2023 @ 20:49:54 | Current Revision | ||
---|---|---|---|
Content | |||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Tradicionalmente, considera-se uma boa prática comentar o código. Há algum tempo, tem-se revisto este conceito. Na <a href="https:/ /liferay.com" >Liferay</a>, por exemplo, seguimos uma política de não comentar código. Pessoalmente, sou um entusiasta desta filosofia. Mas não quero apresentar ou defender esta estratégia: há muito <a href="https:/ /blog.codinghorror.com/coding- without-comments/ ">material</a> bom sobre <a href="https:/ /www.youtube.com/watch?v= 2a_ytyt9sf8">isto</a>. Quero discutir uma questão em aberto.</p> | Unchanged: <p>Tradicionalmente, considera-se uma boa prática comentar o código. Há algum tempo, tem-se revisto este conceito. Na <a href="https:/ /liferay.com" >Liferay</a>, por exemplo, seguimos uma política de não comentar código. Pessoalmente, sou um entusiasta desta filosofia. Mas não quero apresentar ou defender esta estratégia: há muito <a href="https:/ /blog.codinghorror.com/coding- without-comments/ ">material</a> bom sobre <a href="https:/ /www.youtube.com/watch?v= 2a_ytyt9sf8">isto</a>. Quero discutir uma questão em aberto.</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Quem comenta quer transmitir alguma informação importante. Que informação é essa? E, mais importante ainda, onde podemos registrá-la? Vejamos algumas alternativas.</p> | Unchanged: <p>Quem comenta quer transmitir alguma informação importante. Que informação é essa? E, mais importante ainda, onde podemos registrá-la? Vejamos algumas alternativas.</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:heading --> | Unchanged: <!-- wp:heading --> | ||
Unchanged: <h2>O que essas linhas fazem?</h2> | Unchanged: <h2>O que essas linhas fazem?</h2> | ||
Unchanged: <!-- /wp:heading --> | Unchanged: <!-- /wp:heading --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Os <em>nomes de funções</em> são excelentes para explicar <em>o que</em> o código faz. Se um bloco de código precisa de um comentário, considere extraí-lo para uma função ou classe. O nome da entidade já esclarecerá seu propósito.</p> | Unchanged: <p>Os <em>nomes de funções</em> são excelentes para explicar <em>o que</em> o código faz. Se um bloco de código precisa de um comentário, considere extraí-lo para uma função ou classe. O nome da entidade já esclarecerá seu propósito.</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Observe, por exemplo, as linhas abaixo, retiradas <a href="https:/ /github.com/liferay/liferay- portal/blob/c80c42d75b23ca8ec30153f94c88263dd468f889~/ modules/apps/ forms-and-workflow/ calendar/calendar-test/src/ testIntegration/java/com/ liferay/calendar/util/test/ CalendarUtilTest.java#L117-L121">desta classe de testes</a>:</p> | Unchanged: <p>Observe, por exemplo, as linhas abaixo, retiradas <a href="https:/ /github.com/liferay/liferay- portal/blob/c80c42d75b23ca8ec30153f94c88263dd468f889~/ modules/apps/ forms-and-workflow/ calendar/calendar-test/src/ testIntegration/java/com/ liferay/calendar/util/test/ CalendarUtilTest.java#L117-L121">desta classe de testes</a>:</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:code --> | Unchanged: <!-- wp:code --> | ||
Unchanged: <pre class="wp-block- code"><code>Assert.assertNotNull( recurrence); | Unchanged: <pre class="wp-block- code"><code>Assert.assertNotNull( recurrence); | ||
Unchanged: Assert.assertNull( recurrence.getUntilJCalendar()); | Unchanged: Assert.assertNull( recurrence.getUntilJCalendar()); | ||
Unchanged: Assert.assertEquals(0, recurrence.getCount( ));</code></pre> | Unchanged: Assert.assertEquals(0, recurrence.getCount( ));</code></pre> | ||
Unchanged: <!-- /wp:code --> | Unchanged: <!-- /wp:code --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Essas linhas verificam se a <a href="https:/ /icalendar.org/iCalendar- RFC-5545/3-8- 5-3-recurrence- rule.html">RRule</a> de um evento tem certas propriedades: ela deve existir, ter um "<em>until</em>" <a href="https:/ /docs.oracle.com/javase/8/ docs/api/java/ util/Calendar.html" ><code>Calendar</code></a> nulo e uma contagem de zero.</p> | Unchanged: <p>Essas linhas verificam se a <a href="https:/ /icalendar.org/iCalendar- RFC-5545/3-8- 5-3-recurrence- rule.html">RRule</a> de um evento tem certas propriedades: ela deve existir, ter um "<em>until</em>" <a href="https:/ /docs.oracle.com/javase/8/ docs/api/java/ util/Calendar.html" ><code>Calendar</code></a> nulo e uma contagem de zero.</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Os conceitos são complexos; eu mesmo me confundiria ao reler estes <em>asserts</em>. Um comentário poderia explicá-los. Mas <a href="https:/ /github.com/liferay/liferay- portal/commit/ c80c42d75b23ca8ec30153f94c88263dd468f889">este commit</a> já esclareceu tudo ao mover essas linhas para um método e invocá-lo: </p> | Unchanged: <p>Os conceitos são complexos; eu mesmo me confundiria ao reler estes <em>asserts</em>. Um comentário poderia explicá-los. Mas <a href="https:/ /github.com/liferay/liferay- portal/commit/ c80c42d75b23ca8ec30153f94c88263dd468f889">este commit</a> já esclareceu tudo ao mover essas linhas para um método e invocá-lo: </p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:code --> | Unchanged: <!-- wp:code --> | ||
Unchanged: <pre class="wp-block- code"><code>assertRepeatsForever( recurrence);< /code></pre> | Unchanged: <pre class="wp-block- code"><code>assertRepeatsForever( recurrence);< /code></pre> | ||
Unchanged: <!-- /wp:code --> | Unchanged: <!-- /wp:code --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Aquelas asserções verificavam se o evento se repete eternamente! Nenhum comentário foi necessário — felizmente, pois estes <em>asserts</em> estavam em vários testes.</p> | Unchanged: <p>Aquelas asserções verificavam se o evento se repete eternamente! Nenhum comentário foi necessário — felizmente, pois estes <em>asserts</em> estavam em vários testes.</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:heading --> | Unchanged: <!-- wp:heading --> | ||
Unchanged: <h2>O que está acontecendo?</h2> | Unchanged: <h2>O que está acontecendo?</h2> | ||
Unchanged: <!-- /wp:heading --> | Unchanged: <!-- /wp:heading --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Se o comentário iria explicar algo relevante em tempo de execução, considere transformá-lo em uma mensagem de log! Note o exempo abaixo.</p> | Unchanged: <p>Se o comentário iria explicar algo relevante em tempo de execução, considere transformá-lo em uma mensagem de log! Note o exempo abaixo.</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:code --> | Unchanged: <!-- wp:code --> | ||
Unchanged: <pre class="wp-block- code"><code>if (Validator.isBlank( serviceAccountKey)) { | Unchanged: <pre class="wp-block- code"><code>if (Validator.isBlank( serviceAccountKey)) { | ||
Unchanged: // If no credentials are set for GCS Store, the library will | Unchanged: // If no credentials are set for GCS Store, the library will | ||
Deleted: // Application Default Credentials. | Added: // use Application Default Credentials. | ||
Unchanged: _googleCredentials = | Unchanged: _googleCredentials = | ||
Unchanged: ServiceAccountCredentials.getApplicationDefault(); | Unchanged: ServiceAccountCredentials.getApplicationDefault(); | ||
Unchanged: } | Unchanged: } | ||
Unchanged: else { | Unchanged: else { | ||
Unchanged: _googleCredentials = ServiceAccountCredentials.fromStream( | Unchanged: _googleCredentials = ServiceAccountCredentials.fromStream( | ||
Unchanged: new ByteArrayInputStream( serviceAccountKey.getBytes())); | Unchanged: new ByteArrayInputStream( serviceAccountKey.getBytes())); | ||
Unchanged: }</code></pre> | Unchanged: }</code></pre> | ||
Unchanged: <!-- /wp:code --> | Unchanged: <!-- /wp:code --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Deleted: <p>Este comentário pode relevante para quem lê o código. Contudo, seria <em>crucial</em> para alguém investigando um problema de autenticação. Por isso, na prática, <a href="https:/ /github.com/liferay/liferay- portal/commit/ 3c431cbdc4eabb0eb7581b27c8eeae622ca768b0">escolhi logar uma mensagem</a>:</p> | Added: <p>Este comentário pode ser relevante para quem lê o código. Contudo, seria <em>crucial</em> para alguém investigando um problema de autenticação. Por isso, na prática, <a href="https:/ /github.com/liferay/liferay- portal/commit/ 3c431cbdc4eabb0eb7581b27c8eeae622ca768b0">escolhi logar uma mensagem</a>:</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:code --> | Unchanged: <!-- wp:code --> | ||
Unchanged: <pre class="wp-block- code"><code>if (Validator.isBlank( serviceAccountKey)) { | Unchanged: <pre class="wp-block- code"><code>if (Validator.isBlank( serviceAccountKey)) { | ||
Unchanged: if (_log.isInfoEnabled()) { | Unchanged: if (_log.isInfoEnabled()) { | ||
Unchanged: _log.info( | Unchanged: _log.info( | ||
Unchanged: "No credentials set for GCS Store. Library will use " + | Unchanged: "No credentials set for GCS Store. Library will use " + | ||
Unchanged: "Application Default Credentials."); | Unchanged: "Application Default Credentials."); | ||
Unchanged: } | Unchanged: } | ||
Unchanged: _googleCredentials = | Unchanged: _googleCredentials = | ||
Unchanged: ServiceAccountCredentials.getApplicationDefault(); | Unchanged: ServiceAccountCredentials.getApplicationDefault(); | ||
Unchanged: } | Unchanged: } | ||
Unchanged: else { | Unchanged: else { | ||
Unchanged: _googleCredentials = ServiceAccountCredentials.fromStream( | Unchanged: _googleCredentials = ServiceAccountCredentials.fromStream( | ||
Unchanged: new ByteArrayInputStream( serviceAccountKey.getBytes())); | Unchanged: new ByteArrayInputStream( serviceAccountKey.getBytes())); | ||
Unchanged: }</code></pre> | Unchanged: }</code></pre> | ||
Unchanged: <!-- /wp:code --> | Unchanged: <!-- /wp:code --> | ||
Unchanged: <!-- wp:heading --> | Unchanged: <!-- wp:heading --> | ||
Deleted: <h2>Por que | Added: <h2>Por que este código está aqui?</h2> | ||
Unchanged: <!-- /wp:heading --> | Unchanged: <!-- /wp:heading --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Comentários para explicar <em>por que</em> algumas linhas estão ali também são comuns. Um local melhor para compartilhar essas informações são as <em>mensagens de commits</em>.</p> | Unchanged: <p>Comentários para explicar <em>por que</em> algumas linhas estão ali também são comuns. Um local melhor para compartilhar essas informações são as <em>mensagens de commits</em>.</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Estes dias, por exemplo, me pediram para ajudar com um código em que trabalhei anos atrás. Lendo uma JSP — lembre-se, anos atrás — eu encontrei <a href="https:/ /github.com/liferay/liferay- portal/blob/043118eadf7c90c5d0182a6f7b5812472ebc142c/ modules/dxp/apps/forms-and- workflow/portal-workflow/ portal-workflow- kaleo-designer- web/src/main/ resources/META- INF/resources/ designer/kaleo_ definition_version_ action.jsp#L29-L34">essas linhas</a>:</p> | Unchanged: <p>Estes dias, por exemplo, me pediram para ajudar com um código em que trabalhei anos atrás. Lendo uma JSP — lembre-se, anos atrás — eu encontrei <a href="https:/ /github.com/liferay/liferay- portal/blob/043118eadf7c90c5d0182a6f7b5812472ebc142c/ modules/dxp/apps/forms-and- workflow/portal-workflow/ portal-workflow- kaleo-designer- web/src/main/ resources/META- INF/resources/ designer/kaleo_ definition_version_ action.jsp#L29-L34">essas linhas</a>:</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:code --> | Unchanged: <!-- wp:code --> | ||
Unchanged: <pre class="wp-block- code"><code>< liferay-portlet:renderURL portletName="<%= KaleoDesignerPortletKeys.KALEO_DESIGNER %>" var="viewURL"> | Unchanged: <pre class="wp-block- code"><code>< liferay-portlet:renderURL portletName="<%= KaleoDesignerPortletKeys.KALEO_DESIGNER %>" var="viewURL"> | ||
Unchanged: <portlet:param name="mvcPath" value="/designer/ view_kaleo_definition_ version.jsp" /> | Unchanged: <portlet:param name="mvcPath" value="/designer/ view_kaleo_definition_ version.jsp" /> | ||
Unchanged: <portlet:param name="redirect" value="<%= currentURL %>" /> | Unchanged: <portlet:param name="redirect" value="<%= currentURL %>" /> | ||
Unchanged: <portlet:param name="name" value="<%= kaleoDefinitionVersion.getName() %>" /> | Unchanged: <portlet:param name="name" value="<%= kaleoDefinitionVersion.getName() %>" /> | ||
Unchanged: <portlet:param name="draftVersion" value="<%= kaleoDefinitionVersion.getVersion() %>" /> | Unchanged: <portlet:param name="draftVersion" value="<%= kaleoDefinitionVersion.getVersion() %>" /> | ||
Unchanged: </liferay- portlet:renderURL> </code></pre> | Unchanged: </liferay- portlet:renderURL> </code></pre> | ||
Unchanged: <!-- /wp:code --> | Unchanged: <!-- /wp:code --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Esta <em>tag</em> está gerando uma URL para ser utilizada em outro lugar. Mas meus olhos treinados acharam estranho aquele parâmetro <code>portletName</code>. Este valor costumar ser definido automaticamente.</p> | Unchanged: <p>Esta <em>tag</em> está gerando uma URL para ser utilizada em outro lugar. Mas meus olhos treinados acharam estranho aquele parâmetro <code>portletName</code>. Este valor costumar ser definido automaticamente.</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Um <code>git blame</code> esclareceu tudo, quando encontrei <a href="https:/ /github.com/liferay/liferay- portal/commit/ 043118eadf7c90c5d0182a6f7b5812472ebc142c">este commit</a>. A mensagem é clara:</p> | Unchanged: <p>Um <code>git blame</code> esclareceu tudo, quando encontrei <a href="https:/ /github.com/liferay/liferay- portal/commit/ 043118eadf7c90c5d0182a6f7b5812472ebc142c">este commit</a>. A mensagem é clara:</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:quote --> | Unchanged: <!-- wp:quote --> | ||
Unchanged: <blockquote class="wp-block-quote"><!-- wp:paragraph --> | Unchanged: <blockquote class="wp-block-quote"><!-- wp:paragraph --> | ||
Unchanged: <p>LPS-74977 / LPS-73731 By making the render URL explicitly use the Kaleo Designer name, it will be valid when rendered in another portlet.</p> | Unchanged: <p>LPS-74977 / LPS-73731 By making the render URL explicitly use the Kaleo Designer name, it will be valid when rendered in another portlet.</p> | ||
Unchanged: <!-- /wp:paragraph --></blockquote> | Unchanged: <!-- /wp:paragraph --></blockquote> | ||
Unchanged: <!-- /wp:quote --> | Unchanged: <!-- /wp:quote --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Entendi! Este código provavelmente vai ser invocado por algum outro portlet. Neste caso, o valor seria automaticamente setado pela outra aplicação, e por alguma razão queremos evitar isso.</p> | Unchanged: <p>Entendi! Este código provavelmente vai ser invocado por algum outro portlet. Neste caso, o valor seria automaticamente setado pela outra aplicação, e por alguma razão queremos evitar isso.</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>(Por esta razão, aliás, prefiro <em>commits</em> pequenos: eles facilitam descobrir a razão de trechos de código bem específicos. É como se <em>todas</em> as linhas de código tivessem um comentário! Não é uma posição unânime, porém: há quem prefira <em>commits</em> maiores.)</p> | Unchanged: <p>(Por esta razão, aliás, prefiro <em>commits</em> pequenos: eles facilitam descobrir a razão de trechos de código bem específicos. É como se <em>todas</em> as linhas de código tivessem um comentário! Não é uma posição unânime, porém: há quem prefira <em>commits</em> maiores.)</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>A razão da linha foi esclarecida. Mas por que ela pode ser invocada de outra aplicação? Isto não é usual...</p> | Unchanged: <p>A razão da linha foi esclarecida. Mas por que ela pode ser invocada de outra aplicação? Isto não é usual...</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:heading --> | Unchanged: <!-- wp:heading --> | ||
Unchanged: <h2>Por que esta mudança foi feita?</h2> | Unchanged: <h2>Por que esta mudança foi feita?</h2> | ||
Unchanged: <!-- /wp:heading --> | Unchanged: <!-- /wp:heading --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Um código bem escrito explica <em>como</em> algo foi implementado. A mensagem de <em>commit</em> esclarece o <em>porquê</em>, mas em um contexto local. Como explicar a motivação mais ampla por trás de um código sem recorrer a comentários?</p> | Unchanged: <p>Um código bem escrito explica <em>como</em> algo foi implementado. A mensagem de <em>commit</em> esclarece o <em>porquê</em>, mas em um contexto local. Como explicar a motivação mais ampla por trás de um código sem recorrer a comentários?</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Os <em>tíquetes do issue tracker</em> são excelentes para isto. Normalmente escritos para guiar o desenvolvimento, esses documentos ajudam demais na interpretação do código. Se adicionarmos a chave do tíquete à mensagem de <em>commit</em>, podemos rastrear as razões.</p> | Unchanged: <p>Os <em>tíquetes do issue tracker</em> são excelentes para isto. Normalmente escritos para guiar o desenvolvimento, esses documentos ajudam demais na interpretação do código. Se adicionarmos a chave do tíquete à mensagem de <em>commit</em>, podemos rastrear as razões.</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Voltando ao exemplo acima. Descobrimos que uma linha permite usar o mesmo código em vários portlets. Mas isso raramente é necessário. Por que precisamos reutilizar o código neste caso? Por sorte, a mensagem menciona dois tíquetes. Fui verificar o mais antigo; cheguei a <a href="https:/ /liferay.atlassian.net/browse/ LPSA-64324">LPSA- 64324</a>:</p> | Unchanged: <p>Voltando ao exemplo acima. Descobrimos que uma linha permite usar o mesmo código em vários portlets. Mas isso raramente é necessário. Por que precisamos reutilizar o código neste caso? Por sorte, a mensagem menciona dois tíquetes. Fui verificar o mais antigo; cheguei a <a href="https:/ /liferay.atlassian.net/browse/ LPSA-64324">LPSA- 64324</a>:</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:quote --> | Unchanged: <!-- wp:quote --> | ||
Unchanged: <blockquote class="wp-block-quote"><!-- wp:paragraph --> | Unchanged: <blockquote class="wp-block-quote"><!-- wp:paragraph --> | ||
Unchanged: <p>[Information Architecture] EE - As a portal admin, I would like to access all workflow portlets from the control panel section under the same tab.</p> | Unchanged: <p>[Information Architecture] EE - As a portal admin, I would like to access all workflow portlets from the control panel section under the same tab.</p> | ||
Unchanged: <!-- /wp:paragraph --></blockquote> | Unchanged: <!-- /wp:paragraph --></blockquote> | ||
Unchanged: <!-- /wp:quote --> | Unchanged: <!-- /wp:quote --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>O título já ajuda, e o texto esclarece de vez. Por razões de usabilidade, três aplicações diferentes passaram a aparecer em abas de um mesmo portlet. Faz todo sentido!</p> | Unchanged: <p>O título já ajuda, e o texto esclarece de vez. Por razões de usabilidade, três aplicações diferentes passaram a aparecer em abas de um mesmo portlet. Faz todo sentido!</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:heading --> | Unchanged: <!-- wp:heading --> | ||
Unchanged: <h2>Os comentários que a gente gosta</h2> | Unchanged: <h2>Os comentários que a gente gosta</h2> | ||
Unchanged: <!-- /wp:heading --> | Unchanged: <!-- /wp:heading --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>É importante destacar que tentamos evitar comentários desorganizados, que se entrelaçam no código e tentam explicar trechos difíceis de entender. Há vários comentários, frequentemente com formatos padronizados, que não atrapalham a leitura. Um exemplo óbvio são os cabeçalhos de <em>copyright</em>.</p> | Unchanged: <p>É importante destacar que tentamos evitar comentários desorganizados, que se entrelaçam no código e tentam explicar trechos difíceis de entender. Há vários comentários, frequentemente com formatos padronizados, que não atrapalham a leitura. Um exemplo óbvio são os cabeçalhos de <em>copyright</em>.</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Outra maneira de usar comentários efetivamente é a <a href="https:/ /pt.wikipedia.org/ wiki/Programa%C3%A7%C3%A3o_ letrada">programação letrada</a>. Neste estilo de programação, os comentários são a estrela do show: o código-fonte contem mais prosa do que código executável. Isto é útil quando explicar o algoritmo é mais importante do que lê-lo, como em pesquisas acadêmicas e análise de dados. Não por acaso, é o paradigma de ferramentas populares como <a href="https:/ /jupyter.org/">Jupyter Notebook</a> e <a href="https:/ /quarto.org/" >Quarto</a>.</p> | Unchanged: <p>Outra maneira de usar comentários efetivamente é a <a href="https:/ /pt.wikipedia.org/ wiki/Programa%C3%A7%C3%A3o_ letrada">programação letrada</a>. Neste estilo de programação, os comentários são a estrela do show: o código-fonte contem mais prosa do que código executável. Isto é útil quando explicar o algoritmo é mais importante do que lê-lo, como em pesquisas acadêmicas e análise de dados. Não por acaso, é o paradigma de ferramentas populares como <a href="https:/ /jupyter.org/">Jupyter Notebook</a> e <a href="https:/ /quarto.org/" >Quarto</a>.</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Mais relevante ainda, ferramentas como <a href="https:/ /www.oracle.com/technical- resources/articles/ java/javadoc- tool.html">Javadoc</a>, <a href="https:/ /jsdoc.app/">JSDoc</a>, <a href="https:/ /www.doxygen.nl/ ">Doxygen</a> etc. leem comentários em um formato específico para gerar documentação. Estes comentários não afetam a legibilidade. Pelo contrário: javadocs são ótimos para explicar <em>como usar</em> estas entidades. Combinados com ferramentas como <a href="https:/ /suspensao.blog.br/descrenca/ doctest/">meu querido Doctest</a>, temos até garantias de acurácia e atualidade!</p> | Unchanged: <p>Mais relevante ainda, ferramentas como <a href="https:/ /www.oracle.com/technical- resources/articles/ java/javadoc- tool.html">Javadoc</a>, <a href="https:/ /jsdoc.app/">JSDoc</a>, <a href="https:/ /www.doxygen.nl/ ">Doxygen</a> etc. leem comentários em um formato específico para gerar documentação. Estes comentários não afetam a legibilidade. Pelo contrário: javadocs são ótimos para explicar <em>como usar</em> estas entidades. Combinados com ferramentas como <a href="https:/ /suspensao.blog.br/descrenca/ doctest/">meu querido Doctest</a>, temos até garantias de acurácia e atualidade!</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:heading --> | Unchanged: <!-- wp:heading --> | ||
Unchanged: <h2>Um mundo de possibilidades</h2> | Unchanged: <h2>Um mundo de possibilidades</h2> | ||
Unchanged: <!-- /wp:heading --> | Unchanged: <!-- /wp:heading --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Esses são apenas alguns exemplos de alternativas aos comentários. Há muitas outras opções, como wikis, blogs. Já encontrei a explicação para um código que escrevi no Stack Overflow! Podemos pensar em ainda mais soluções para atender a diferentes necessidades. O ponto principal é que, tendo estas ferramentas à nossa disposição, adicionar comentários diretamente ao código torna-se desnecessário.</p> | Unchanged: <p>Esses são apenas alguns exemplos de alternativas aos comentários. Há muitas outras opções, como wikis, blogs. Já encontrei a explicação para um código que escrevi no Stack Overflow! Podemos pensar em ainda mais soluções para atender a diferentes necessidades. O ponto principal é que, tendo estas ferramentas à nossa disposição, adicionar comentários diretamente ao código torna-se desnecessário.</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Naturalmente, evitar comentários é apenas uma das formas para se escrever código legível. Comentários não são proibidos; de fato, há estratégias que podem torná-los eficazes. No entanto, na minha experiência, comentar indisciplinadamente leva a piores resultados, e essas técnicas ajudam a documentar informações importantes que não cabem diretamente no código.</p> | Unchanged: <p>Naturalmente, evitar comentários é apenas uma das formas para se escrever código legível. Comentários não são proibidos; de fato, há estratégias que podem torná-los eficazes. No entanto, na minha experiência, comentar indisciplinadamente leva a piores resultados, e essas técnicas ajudam a documentar informações importantes que não cabem diretamente no código.</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Você é um adepto da estratégia "sem comentários"? Se sim, que outros meios você usa para transmitir infirmações? Se não, como você faz para ter comentários efetivos? Que tipo de comentário você não vê sendo substituído por essas abordagens? Adoraria escutar suas opiniões.</p> | Unchanged: <p>Você é um adepto da estratégia "sem comentários"? Se sim, que outros meios você usa para transmitir infirmações? Se não, como você faz para ter comentários efetivos? Que tipo de comentário você não vê sendo substituído por essas abordagens? Adoraria escutar suas opiniões.</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> |
Note: Spaces may be added to comparison text to allow better line wrapping.