Hace unos días mi compañero en el Federico Firenze me abrió los ojos y me quitó cierta manía que tenía de utilizar archivos "include" para guardar cadenas/recursos en los proyectos que venía llevando a cabo en Delphi.
Se trata de evitar duplicar recursos en los ejecutables. Se trata de ver la diferencia entre incluir archivos (nunca mejor dicho, veremos luego porqué) con cadenas/recursos, o añadir una o más unidades a nuestros proyectos que contengan dichas cadenas/recursos.
Verás. Yo venía haciendo algo como esto en mis programas:
unit Pruebas; interface uses Windows, SysUtils {...}; implementation {$I 'incrsPrograma.inc'} {...} end.
Y dentro del archivo "rsPrograma.inc", a modo de ejemplo, encontraríamos algo como:
resourcestring rsVersionPrograma = '1.0'; rsPaginaWebPrograma = 'http://www.bitacora.davidesperalta.com'; rsCorreoSoportePrograma = 'correo-soporte@programa.com'; {...}
Es decir, añadía en las unidades que precisaban de las cadenas/recursos el archivo "rsPrograma.inc", de modo que podía hacer uso de dichas cadenas/recursos dentro de las unidades en que esto fuera menester.
Ahora bien. ¿Dónde está el problema? El problema está en que los archivos "include" se incluyen tal cual en la unidad, valga la redundancia, se incluyen, como me dijo Federico, "al estilo de C", y de PHP... por ejemplo.
Se incluyen... se incluyen... se incluyen... y terminan incluyéndose tantos como se quiera... pero duplicándose, ¿se entiende? Al final tendremos en el archivo ejecutable tres "rsVersionPrograma", tres "rsPaginaWebPrograma", y tres "rsCorreoSoportePrograma", si incluimos el archivo tres veces,... y dieciocho si lo hacemos dieciocho veces...
Yo no veía ese problema y en dos o tres proyectos que tengo en marcha hacía uso de los archivos "include" como venía haciéndolo desde que no recuerdo dónde aprendí (mal) a hacer uso de ellos. Poder incluir donde necesitemos un archivo "externo" puede ser muy útil, pero, en este caso, para usarlos como contenedores de recursos/cadenas, parece que no sólo no son útiles, sino que no deben usarse.
Y bien. ¿Cuál es la solución? ¿Qué hacemos si aún así queremos seguir usando determinados recursos/cadenas y queremos agruparlas en un archivo de modo que estén disponibles para todas aquellas unidades que lo necesiten? La solución es, precisamente, usar una unidad.
Una unidad tal que esta, siguiendo con el ejemplo:
unit URecursos; interface resourcestring rsVersionPrograma = '1.0'; rsPaginaWebPrograma = 'http://www.bitacora.davidesperalta.com'; rsCorreoSoportePrograma = 'correo-soporte@programa.com'; implementation end.
Y se acabó duplicar recursos/cadenas en el ejecutable. Todas las unidades que precisen de ellos pueden añadir a alguna de sus cláusulas "uses" la unidad "URecursos.pas".
No importa cuántas unidades hagan uso de los recursos/cadenas, en el ejecutable no se duplicarán los recursos, puesto que añadir, hacer uso de una unidad, no es igual que incluir un archivo.
Luego de la pedrada en la frente que me dio Federico, no tuve por menos que agradecerle que me hiciera caer del burro, y, por supuesto, ponerme a actualizar los proyectos que mantengo de modo que dejaran de usar archivos "include" como venían haciéndolo.
Y lo mejor de todo: se me quitó la manía. Tengo claro que no debo usar archivos "include" sino cuando son verdaderamente necesarios, y en ningún caso para guardar en ellos recursos/cadenas, como venía haciendo, sino utilizar una o varias unidades para ello. Y luego de escribir este rollo todavía lo tengo más claro.
¡Gracias a Federico Firenze!