{"id":74,"date":"2013-11-27T16:22:00","date_gmt":"2013-11-27T16:22:00","guid":{"rendered":"http:\/\/esferas.org\/msqlu\/2013\/11\/27\/resulta-descorazonador-revisar-tu-propio-codigo\/"},"modified":"2013-11-27T16:22:00","modified_gmt":"2013-11-27T16:22:00","slug":"resulta-descorazonador-revisar-tu-propio-codigo","status":"publish","type":"post","link":"https:\/\/esferas.org\/msqlu\/2013\/11\/27\/resulta-descorazonador-revisar-tu-propio-codigo\/","title":{"rendered":"Resulta descorazonador revisar tu propio c\u00f3digo &#8230;"},"content":{"rendered":"<div class='__iawmlf-post-loop-links' style='display:none;' data-iawmlf-post-links='[{&quot;id&quot;:1314,&quot;href&quot;:&quot;http:\\\/\\\/search.cpan.org\\\/~dconway\\\/Perl6-Form-0.04\\\/Form.pm&quot;,&quot;archived_href&quot;:&quot;https:\\\/\\\/web-wp.archive.org\\\/web\\\/20180616041437\\\/http:\\\/\\\/search.cpan.org\\\/~dconway\\\/Perl6-Form-0.04\\\/Form.pm&quot;,&quot;redirect_href&quot;:&quot;https:\\\/\\\/metacpan.org\\\/pod\\\/release\\\/DCONWAY\\\/Perl6-Form-0.04\\\/Form.pm&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2026-04-17 07:32:34&quot;,&quot;http_code&quot;:200}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2026-04-17 07:32:34&quot;,&quot;http_code&quot;:200},&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:1315,&quot;href&quot;:&quot;http:\\\/\\\/manpages.debian.org\\\/cgi-bin\\\/man.cgi?query=dwww&amp;apropos=0&amp;sektion=0&amp;manpath=Debian+7.0+wheezy&amp;format=html&amp;locale=en&quot;,&quot;archived_href&quot;:&quot;&quot;,&quot;redirect_href&quot;:&quot;https:\\\/\\\/manpages.debian.org\\\/cgi-bin\\\/man.cgi?query=dwww&quot;,&quot;checks&quot;:[],&quot;broken&quot;:false,&quot;last_checked&quot;:null,&quot;process&quot;:&quot;done&quot;},{&quot;id&quot;:1316,&quot;href&quot;:&quot;http:\\\/\\\/moose.iinteractive.com\\\/es&quot;,&quot;archived_href&quot;:&quot;&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[],&quot;broken&quot;:false,&quot;last_checked&quot;:null,&quot;process&quot;:&quot;done&quot;}]'><\/div>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"perl\" src=\"https:\/\/esferas.org\/mt\/msqlu\/logos\/perl-logo.png\" class=\"mt-image-left\" style=\"float: left; margin: 0 20px 20px 0;\" height=\"75\" width=\"145\" \/>&#8230; escrito tiempo atr\u00e1s y darse cuenta de todas sus carencias. Una deuda t\u00e9cnica que estos d\u00edas estoy pagando a lo bestia.<\/p>\n<p><!--more--><\/p>\n<h4>Hace algunos a\u00f1os &#8230;<\/h4>\n<p>&#8230; , cuando no estaba m\u00e1s s\u00f3lo que la una, mi compa\u00f1ero de trabajo y yo escribimos un servidor de trabajos de impresi\u00f3n para intentar resolver un problema cada vez mayor: los listados de la gesti\u00f3n comercial de la empresa.<\/p>\n<p>Empezaban a ser una pesadilla de mantener porque el lenguaje en el que est\u00e1 escrito dicho programa de gesti\u00f3n (al que cari\u00f1osamente llam\u00e9 <em>Adriano<\/em>) obliga a que los informes impresos se creen como si de una impresora matricial se tratase. Es decir, que en cada listado hay que detallar columna a columna y l\u00ednea a l\u00ednea todo lo que va a ir escrito, evitando que se desborde en las l\u00edneas.<\/p>\n<p>S\u00ed, tiene alg\u00fan tipo de control de saltos de p\u00e1gina, pero siempre termin\u00e1bamos teniendo uno paralelo dada su poca flexibilidad, lo que significaba luchar contra los datos, el lenguaje de programaci\u00f3n y los l\u00edmites f\u00edsicos de la pagina. Los efectos tipogr\u00e1ficos consist\u00edan en enviar secuencias en lenguaje IBM Propinter o PCL directamente a la impresora y los desbordes de l\u00ednea y p\u00e1gina aparec\u00edan cont\u00ednuamente. Jo, qu\u00e9 peleas, sobre todo cuando cambi\u00e1bamos el modelo de la impresora y hab\u00eda que resucitar un arcano script en Perl que cambiaba pseudoc\u00f3digos por secuencias de control reales.<\/p>\n<p>Como el susodicho lenguaje de <em>cuarta generaci\u00f3n<\/em> maneja textos con tanta sutileza como un panzer en un trigal, al final le ten\u00edamos rodeado de scripts auxiliares en Perl y siempre, pero siempre, siempre, encontr\u00e1bamos alguna excepci\u00f3n que romp\u00eda el resultado. Un asco.<\/p>\n<p>Con todo esto en mente (y teniendo en cuenta que no pod\u00edamos actualizar el sistema por si el montaje mor\u00eda del todo) pensamos en que ser\u00eda muy c\u00f3modo mover la generaci\u00f3n de impresos a un programa Perl moderno, en otra m\u00e1quina y limitarnos desde <em>Adriano<\/em> a enviarle datos en formato XML convenientemente auxiliados por una capa de funciones de manera que algo como<\/p>\n<pre>put stream standard<br \/>   column 54,<br \/>   \"Sumas.....\",<br \/>   column 64,<br \/>   (detalle.a_mes1 + detalle.b_mes1) using f1 clipped &amp;&amp; \" \" &amp;&amp;<br \/>   (detalle.a_mes2 + detalle.b_mes2) using f1 clipped &amp;&amp; \" \" &amp;&amp;<br \/>   diferencia(detalle.a_mes1 + detalle.b_mes1, detalle.a_mes2 + <br \/>   detalle.b_mes2), <br \/>   skip 2<\/pre>\n<p>quedase en algo m\u00e1s cuco y result\u00f3n<\/p>\n<pre>call impresor_abrir_registro( 'detail' )<br \/><br \/>call impresor_par( 'consignatario', f_lin.destinatario )<br \/>call impresor_par( 'portes', evalcond(f_lin.portes,'=','d',<br \/>                msgtext(160), msgtext(150)))<br \/>call impresor_par( 'fecha', f_cab.fecha )<br \/>call impresor_par( 'agencia', agencia )<br \/>call impresor_par( 'bultos', num_bultos left )<br \/>call impresor_par( 'kilos', f_lin.kilos left )<br \/><br \/>call impresor_cerrar_registro()<\/pre>\n<blockquote cite=\"mid:CA+bJJbz_6mCoFz07F6vZQaqJBy10iO2qB6e2r2YLkhb04Ohepw@mail.gmail.com\" type=\"cite\"><\/blockquote>\n<p>Al menos ya no ten\u00edamos que preocuparnos de cortar, dar forma y escribir cada valor en cada columna; nos limit\u00e1bamos\u00a0 a generar un flujo de registros y a envi\u00e1rselo al impresor.<\/p>\n<p>Como la idea molaba nos pusimos a ello con toda nuestra buena intenci\u00f3n y en un plazo no demasiado largo ten\u00edamos resultados que, si bien no eran tan aparentes y resultones -porque no pudimos emplear m\u00e1s que texto plano-, s\u00ed que relajaban mucho la tensi\u00f3n a la hora de crear nuevos listados o realizar cambios en la gesti\u00f3n comercial.<\/p>\n<p>Decidimos utilizar la funci\u00f3n <em>form<\/em> de Perl6 que ten\u00edamos disponible en el m\u00f3dulo <a href=\"http:\/\/search.cpan.org\/~dconway\/Perl6-Form-0.04\/Form.pm\">Perl6::Forms<\/a> y la cosa funcionaba bien porque pod\u00edamos escribir el listado en un archivo de texto y luego tratarlo con Perl. Perd\u00edamos la posiblidad de emplear negritas, it\u00e1licas y dem\u00e1s, y parte de la l\u00f3gica del listado -como los acumulados y los contadores- deb\u00eda trasladarse al servidor de impresi\u00f3n pero merec\u00eda la pena.<\/p>\n<p>Esta es una muestra de c\u00f3mo se define un registro de detalle ahora:<\/p>\n<pre>&lt;detail&gt;<br \/>    template = &lt;&lt;EOF<br \/>    * {&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;}  Bultos      {&gt;&gt;&gt;&gt;&gt;}<br \/>      {VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV}  Kilos   {&gt;&gt;.&gt;&gt;&gt;,&lt;0}<br \/>      {VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV}  Portes {&gt;&gt;&gt;&gt;&gt;&lt;&lt;&lt;&lt;&lt;}<br \/>      {VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV}  <br \/>      {VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV}  <br \/>      Observaciones: <br \/>          {&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;}<br \/>          {VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV}<br \/>    -----------------------------------------------------------------------------<br \/>    EOF<br \/>    <br \/>    fields = direccion, bultos, kilos, portes, observaciones<br \/>    accum =  bultos, kilos <br \/><br \/>    &lt;form&gt;<br \/>        bullet  =   \"* \"<br \/>    &lt;\/form&gt;<br \/>&lt;\/detail&gt;<br \/><br \/><\/pre>\n<p>Hoy, a\u00f1os despu\u00e9s de haber creado aqu\u00e9l programa, y ante la tarea de a\u00f1adirle algunos listados y retocar otros me he dado cuenta de que no lo hicimos bien. El concepto s\u00ed, la implementaci\u00f3n no.<\/p>\n<h4>\u00bf Qu\u00e9 fallos le encuentro ?<\/h4>\n<ul>\n<li>No tiene unos valores predefinidos sanos. Est\u00e1 demasiado anclado a una instalaci\u00f3n concreta y en algunos aspectos cogido con pinzas. Normalizar el paquete Debian (porque el que ten\u00eda no funcionaba) ha consistido en deshechar todo lo anterior y comenzar de cero con el directorio <em>debian\/.\u00a0<\/em>Digo yo que no deber\u00eda haber sido tan tr\u00e1gico, \u00bf no ?\u00a0<\/li>\n<li>Los mensajes de error que genera son para programadores Perl machotes. El operador medio sufre espamos musculares cuando intenta leerme por tel\u00e9fono una traza de ejecuci\u00f3n resultante de un error. Incluso a m\u00ed me cuesta entender cu\u00e1l es el jodido problema final.<\/li>\n<li>La documentaci\u00f3n del m\u00f3dulo est\u00e1 incompleta. Ahora recuerdo que las malditas prisas nos obligaron a postergar tanto su completado que leerla es una aut\u00e9ntica prueba de f\u00e9. F\u00e9 en que las clases de las que derivan est\u00e9n documentadas o sepan al menos lo que hacen. Y as\u00ed hasta llegar a extremos rid\u00edculos.<\/li>\n<li>El c\u00f3digo tiene partes tan enrevesadas que resulta muy dif\u00edcil de seguir debido a que quiere cubrir demasiados objetivos. El comienzo es bueno, pero seg\u00fan se le a\u00f1aden caracter\u00edsticas (como la copia del resultado v\u00eda SSH o SMB) se nota que entraron a hachazos en el dise\u00f1o general. Mal, muy mal.<\/li>\n<li>Los test. Pr\u00e1cticamente no existen. ni unitarios ni regresivos ni nada que no sea la verificaci\u00f3n sint\u00e1ctica. Las malditas prisas (de nuevo) y los resultados r\u00e1pidamente visibles\u00a0 provocaron que los olvid\u00e1semos y ahora es necesario realizar cirug\u00eda con trozos de c\u00f3digo canibalizados para poner en marcha alg\u00fan tipo de prueba. He tardado d\u00eda y medio en darme cuenta de d\u00f3nde pod\u00eda cambiar una validaci\u00f3n de valores en los campos sin destruirlo todo. Y casi no lo consigo.<\/li>\n<\/ul>\n<h4>\u00bf Qu\u00e9 aprendo de ello ?<\/h4>\n<p>Ahora que trabajo s\u00f3lo me enfrento siempre a los jefes con mis ideas conservadoras sobre la creaci\u00f3n de c\u00f3digo por los retrasos que eso supone. Sigo pensando que es un tiempo bien empleado pero &#8230;<\/p>\n<p>El resultado que persigo es disponer de un paquete de software que pueda instalar (suelo emplear paquetes Debian) y que tras recuperar la configuraci\u00f3n y los datos pueda ponerlo en marcha sin m\u00e1s ajustes ni traumas. Pretendo que cualquier programa que se emplee m\u00e1s de una vez en la empresa se instale del mismo modo que un editor de textos o un navegador. Y por ahora lo estoy consiguiendo a pesar de la presi\u00f3n del d\u00eda a d\u00eda.<\/p>\n<p>Lo que hago ahora es lo siguiente:<\/p>\n<ul>\n<li>Empleo siempre un repositorio Git para todo proyecto.<\/li>\n<li>Antes de escribir c\u00f3digo escribo tests para probarlo:\n<ul>\n<li>Al principio de los principios todo casca, obviamente, pero seg\u00fan voy a\u00f1adi\u00e9ndolo verifico los resultados hasta que se cumplen todos.<\/li>\n<li>Comienzo los test por los de m\u00e1s alto nivel para forzarme as\u00ed a perfilar el interfaz y comprobar si es c\u00f3modo o no.<\/li>\n<li>Los alimento con basura para saber qu\u00e9 puede llegar a dar por v\u00e1lido y no llevarme sorpresas luego.<\/li>\n<\/ul>\n<\/li>\n<li>Guardo los cambios en el repositorio lo m\u00e1s at\u00f3micos posible. No llegar\u00e9 nunca al extremo que tengo entendido emplean en el n\u00facleo de Linux, donde pueden deshechar algunos e incluir otros, pero al menos intento tener la capacidad de eliminar caracter\u00edsticas completas de un plumazo.<\/li>\n<li>Documento todo. A\u00f1ado un test de cobertura de c\u00f3digo para los m\u00f3dulos Perl y no lo doy por v\u00e1lido hasta que no termino por cubrir cada uno de los m\u00e9todos y funciones p\u00fablicas.<\/li>\n<li>Los valores de la configuraci\u00f3n son siempre los m\u00ednimos para que arranque sin problemas o para detectar cu\u00e1ndo no puede arrancar y avisar de ello. Prefiero \u00e9sto a enfrentarme con programas err\u00e1ticos cuando no encuentran las cosas donde creen que est\u00e1n.<\/li>\n<li>Creo un paquete Debian para el software intentando emplear todas las herramientas que existen de manera que no tenga que instalar a mano la documentaci\u00f3n o dar de alta un servicio en el sistema cuando \u00e9ste pueda hacerlo por s\u00ed mismo. El registro de cambios del paquete refleja a mayor nivel lo que todo el software empaquetado significa. Para cambios menores ya existe el del repositorio.<\/li>\n<li>Aunque al principio intent\u00e9 crear p\u00e1ginas web para cada proyecto abandon\u00e9 pronto la idea por la duplicaci\u00f3n de esfuerzos. Un programa como <em>gitweb<\/em> (o similar) y una buena documentaci\u00f3n escrita bastan para realizar consultas. Adem\u00e1s, como todos los m\u00f3dulos y programas Perl incluyen documentaci\u00f3n en formato POD, y \u00e9sta se instala como p\u00e1ginas de manual en el paquete Debian, la parte de desarrollo queda cubierta. Me falta, eso s\u00ed, mejorar esta informaci\u00f3n empleando el formato HTML y programas como <a href=\"http:\/\/manpages.debian.org\/cgi-bin\/man.cgi?query=dwww&amp;apropos=0&amp;sektion=0&amp;manpath=Debian+7.0+wheezy&amp;format=html&amp;locale=en\">dwww<\/a> para poder revisar el c\u00f3digo. Estoy preparando un art\u00edculo sobre ello.<\/li>\n<\/ul>\n<p>Y poco m\u00e1s que decir al respecto por ahora. Tengo pensando cambiar la implementaci\u00f3n del servidor de impresi\u00f3n por un Perl m\u00e1s moderno y legible; a pesar de que utilizando herramientas como <a href=\"http:\/\/moose.iinteractive.com\/es\/\">Moose<\/a> los programas crecen bastante en recursos y tiempo de ejecuci\u00f3n, el ahorro de esfuerzo en el mantenimiento merece la pena.<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8230; escrito tiempo atr\u00e1s y darse cuenta de todas sus carencias. Una deuda t\u00e9cnica que estos d\u00edas estoy pagando a lo bestia.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"1","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","webmentions_disabled_pings":false,"webmentions_disabled":false,"footnotes":""},"categories":[7],"tags":[16,124,125],"class_list":["post-74","post","type-post","status-publish","format-standard","hentry","category-perl","tag-desarrollo","tag-deuda-tecnica","tag-listados"],"_links":{"self":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts\/74","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/comments?post=74"}],"version-history":[{"count":0,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts\/74\/revisions"}],"wp:attachment":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/media?parent=74"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/categories?post=74"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/tags?post=74"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}