Borland ha vendido CodeGear a Embarcadero, nueva casa para Delphi

Pues eso: hilo en los grupos de noticias y ahí están los enlaces a las notas de prensa. Marco Cantú opina también.

A mí me parece bien. La situación de CodeGear dentro de Borland era insostenible. Embarcadero es una empresa sólida, que gira en torno al desarrollo y que se mueve en un sector muy similar a CodeGear.

iptables y vagancia

En el último petardazo del alojamiento, se perdió todo el contenido de este servidor. Pude recuperar la base de datos de Drupal. Pero no el trabajo manual que había hecho con .htaccess para enlazar con los artículos antiguos, los que escribí con Pebble. Había escrito un programa con Delphi para extraer el contenido del XML de Pebble, pero tengo que hacer otro para meterlos en Drupal y la vagancia me puede. Por lo pronto anteayer estuve restaurando el firewall. Una ventaja de que no me visite nadie es que no tengo que preocuparme demasiado por esas cosas, a pesar por ejemplo del reciente exploit para escalada de privilegios del núcleo. Pero ya era hora. He descubierto que la nueva versión de Virtuozzo ya usa iptables con estado, lo que ha simplificado mucho las cosas. Antes que nada, recuperé el script con estado de mi viejo artículo de iptables:

# Reglas por defecto, salida permitida, entrada o redirección prohibidas.
# Para hacer pruebas en remoto casi mejor permitir la entrada hasta estar
# seguros, no vayamos a quedarnos sin conexión.

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Borra las reglas que haya.

iptables   -F INPUT
iptables   -F FORWARD
iptables   -F OUTPUT
# iptables -F -t nat

# Esta instrucción por ejemplo usa el estado: permite el tráfico en conexiones
# ya iniciadas (el inicio se define más abajo).  Nota: venet0 es la interfaz
# de red que en otra máquina podría ser digamos eth0.
iptables -A INPUT -i venet0 -m state --state ESTABLISHED,RELATED -j ACCEPT

# Permitimos todo el tráfico interno dentro de la misma máquina.
iptables -A INPUT -i lo -s 0/0 -d 0/0 -j ACCEPT

# Y finalmente definimos cuándo se permite iniciar una conexión. 
# Incluimos los protocolos ssh (puerto 22), smtp (25), http (80),
# pop3 (110) y https (443)
iptables -A INPUT -p tcp --dport 22   -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp --dport 25   -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp --dport 80   -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp --dport 110  -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp --dport 443  -m state --state NEW -j ACCEPT

# La siguiente línea creo que es innecesaria. El panel de Virtuozzo,
# que escucha por https en el puerto 4643, creo que está "antes" de
# nuestro cortafuegos.
iptables -A INPUT -p tcp --dport 4643 -m state --state NEW -j ACCEPT

Esto está muy bien por la brevedad, pero a diferencia del otro script, el que tenía para iptables sin estado, no incluye el envoltorio para meterlo en el arraque con funciones start, stop y restart. Así que estuve buscando cómo funciona ahora en Debian y encontré este artículo. Está casi bien. Vi que después de ejecutarlo, se puede guardar el estado con:

iptables-save > /etc/firewall-rules

De forma que para que se restaure se pueda usar esta línea:

pre-up iptables-restore < /etc/firewall-rules 

Pero a diferencia de lo que pone el artículo, la tuve que poner en el fichero template, no en el fichero interfaces de /etc/network. Salvo por esa pequeña diferencia, todo parece funcionar como debe.

Todo esto se describe en unos pocos minutos. Hacerlo me hizo estar hasta tarde el jueves. Ayer viernes fue un día lleno de emociones, así que caí en la cama como un ladrillo. Ahora queda la parte en que subo los viejos artículos... ya veremos.

Incluir ficheros DFM condicionalmente

En los últimos meses he participado en la traducción de un programa hecho con Delphi. Conté por aquí los problemas del Translation Manager incluido con Delphi hasta el punto de recomendar que no se use.

En esa última historia contaba cómo terminé por crear una herramienta propia que usa el parser de DFM de la VCL para filtrar los ficheros DFM y sustituir las cadenas de acuerdo a un diccionario. El resultado final es un juego de ficheros DFM en catalán e inglés.

La primera idea fue hacer un script que copiase los fuentes del proyecto a otro directorio, machacase sus DFM con los traducidos y compilase la versión en catalán o inglés. Pero finalmente se me ocurrió la manera de ponerlo todo junto y controlar el idioma con un fichero incluido y $define.

En principio parece fácil. Todas las units que tienen un DFM asociado llevan la siguiente línea, generada automáticamente por el IDE:

{$R *.dfm}

La directriz del compilador R se usa para incluir ficheros de recursos. Los DFM originales eran siempre ficheros de recursos (los que suelen tener la extensión *.RES) con la definición del formulario metida en un bloque binario del tipo RC_DATA. A partir de Delphi 5 (creo) existe la posibilidad de guardar los DFM en disco en formato texto, aunque antes también era posible acceder a ese texto con Alt-F12 o a través del portapapeles. Sea como sea, $R sigue sirviendo para incluir el DFM, aunque sea en formato texto. El asterisco representa el nombre del fichero actual, así que *.dfm en unit1.pas se referiría a unit1.dfm.

Primer intento

Lo más sencillo parece hacer un simple condicional. Por una parte tendríamos la enumeración de idiomas:

{$DEFINE CASTELLANO}
{ DEFINE CATALAN}
{ DEFINE INGLES}

Al faltar el signo del dólar, sólo la primera línea es válida. Pero es fácil cambiar el signo de sitio.

Después podemos usar un condicional. Parece lógico usar lo siguiente:

{$IFDEF CASTELLANO}{$R *.dfm}{$ENDIF}
{$IFDEF CATALAN}{$R *.cat}{$ENDIF}
{$IFDEF INGLES}{$R *.eng}{$ENDIF}

Pero no funciona. Al menos Delphi 6 no se traga como DFM un fichero que tenga extensión .CAT. Creo que el error era algo sobre el formato. En cualquier caso se puede arreglar así:

{$IFDEF CASTELLANO}{$R *.dfm}{$ENDIF}
{$IFDEF CATALAN}{$R *.cat.dfm}{$ENDIF}
{$IFDEF INGLES}{$R *.eng.dfm}{$ENDIF}

Bien, esto funciona. Pero es muy poco práctico tener el define de idioma en cada uno de las units con DFM asociado. Nueva idea: poner todo en un fichero incluido y dejar sólo la directiva de inclusión:

{$I IDIOMA.INC}

Donde lógicamente habríamos puesto lo siguiente:

{$DEFINE CASTELLANO}
{ DEFINE CATALAN}
{ DEFINE INGLES}
 
{$IFDEF CASTELLANO}{$R *.dfm}{$ENDIF}
{$IFDEF CATALAN}{$R *.cat.dfm}{$ENDIF}
{$IFDEF INGLES}{$R *.eng.dfm}{$ENDIF}

La peculiaridad

Esa simple línea no funciona. La peculiaridad de los DFM es que el entorno va a su bola buscando la directriz {$R *.dfm} para saber si tiene que asociar el DFM. El entorno no entra en los ficheros incluidos, así que nos quedaríamos sin poder usar el diseñador de formularios.

Nuevo intento. Pongo no uno, sino dos ficheros incluidos así:

{$DEFINE CASTELLANO}
{ DEFINE CATALAN}
{ DEFINE INGLES}

{$IFDEF CASTELLANO}

Aquí en medio queda el {$R *.dfm}

{$ENDIF}
{$IFDEF CATALAN}{$R *.cat}{$ENDIF}
{$IFDEF INGLES}{$R *.eng}{$ENDIF}

En el principal tendríamos algo así:

{$I IDIOMA.INC}{$R *.dfm}{$I IDIOMAFIN.INC}

Por desgracia a Delphi tampoco le sienta bien que se deje un bloque de compilación condicional abierto entre ficheros.

Lo que sí funciona

Supongo que se puede resolver de varias formas. Lo que he puesto es una línea ligeramente más larga que la anterior.

{$I IDIOMA.INC}{$IFDEF CASTELLANO}{$R *.dfm}{$ELSE}{$IDIOMAFIN.INC}{$ENDIF}

El fichero IDIOMA.INC contiene sólo los defines de idiomas:

{$DEFINE CASTELLANO}
{ DEFINE CATALAN}
{ DEFINE INGLES}

Mientras que el segundo incluido lleva esto:

{$IFDEF CATALAN}{$R *.cat}{$ENDIF}
{$IFDEF INGLES}{$R *.eng}{$ENDIF}

A pesar el condicional el IDE siempre va a pillar el fichero *.dfm, que es lo que veremos siempre en tiempo de diseño, mientras que el compilador escogerá el que se decida en idioma.inc.

Finalmente podemos meter todos los DFM de todos los idiomas en el mismo directorio y controlar el idioma de compilación modificando un solo fichero.

Cosmos Guía Ilustrada

Los reyes magos me han dejado como regalo "Cosmos, Guía Ilustrada" de Giles Sparrow. Se trata de un libro tamaño atlas con fotos de objetos celestes y textos explicativos, aunque la verdad es que de momento paso todo el tiempo mirando las fotos, que por cierto son magníficas.

El material de esta guía está actualizado creo que hasta el año recién terminado. Me suena que las imágenes de la sonda que aterrizó en Titán son así de recientes. Al bueno de Plutón ya lo han degradado.

"Toolkits" de interfaz gráfica

Hace unos días consulté en las news de CodeGear qué opciones hay usando sus herramientas para crear la interfaz de usuario de un programa cuyo "back-end" ha sido escrito en C#. La experiencia ha sido sorprendente por varias razones. No sabía que CodeGear hubiese "congelado" su C#, no sólo como producto independiente, sino también dentro del RAD Studio, en el que no tiene acceso al diseño de formularios. Realmente tampoco esperaba, por eso es bueno preguntar :-) que hubiese buenas opciones para crear la interfaz con Delphi.NET. CodeGear ha desechado Winforms y se ha quedado con el otro toolkit, VCL.NET. La ventaja de éste es que tiene un diseñador de formularios bastante más usable que el de Visual Studio y que las interfaces creadas responden con más agilidad que las construidas con Winforms. En el lado negativo, parece que cualquier librería gráfica no apoyada directamente por Microsoft necesita privilegios especiales para ejecutarse.

Pero si hay algo que me ha sorprendido es la falta de opciones. Hace unos años Microsoft dominaba el mercado de herramientas de programación para escritorio con su Visual Basic "clásico" (quiero decir el que no era .NET) con bastante más usuarios que entornos como Delphi u otros lenguajes de su Visual Studio como el C++. Ahora han dejado de desarrollar ese producto y se vuelcan con .NET donde, sea con VB o con C#, no parece haber opción para crear interfaces de usuario con la misma riqueza que la anterior generación de herramientas. No tengo experiencia directa, corregidme si me equivoco, pero lo que me llega es que el diseñador de formularios es incómodo y los controles son pobres y responden con lentitud. La frase literal ha sido que "parece Java". ¿Es realmente tan malo? ¿Qué han hecho los programadores de VB? ¿Siguen con la versión 6?

Los partidarios de .NET parecen pensar que se arreglará en las próximas versiones, que WPF (que ahora mismo tampoco se encuentra en un estado verdaderamente usable) sustituirá finalmente a Winforms y que el entorno de desarrollo mejorará. Pero es difícil entender por qué se habría de meter Microsoft en semejante berenjenal con vistas al futuro, cuando ya tenía en el presente el dominio, cabreando además a sus programadores y perdiendo una ventaja sobre la competencia.

Si hay un terreno de importancia estratégica en las guerras del software, es el de la programación de interfaces gráficas de usuario. Hay pocas organizaciones que hayan sido capaces de crear un "ecosistema" suficientemente rico y fácil de usar. Los lenguajes emergentes como Ruby o Python suelen tirar más bien por la socorrida interfaz web, ya que para usar Qt o el API de Windows cómodamente es poco menos que imprescindible tener un IDE. A pesar de todos los pesares, Delphi sigue teniendo un algo que no tienen los demás :-)

Con estilo

Hace algún tiempo publiqué esta historia sobre Personal Systems Design, una empresas en la que trabajé al llegar a Madrid, hace ya más de diez años. El fondo del asunto es que, siendo una empresa pequeña, tenía una metodología de trabajo muy superior a empresas mucho más grandes y sonadas en las que trabajé después. Mientras que las empresas grandes se preocupan por la "calidad externa", la del proceso burocrático, PSD buscaba la excelencia en la calidad interna, en hacer programas mejores, con menos fallos, más mantenibles.

Alexander, el artífice de aquel buen hacer, ha tenido el detalle de publicar el manual de estilo de programación de PSD bajo licencia Creative Commons. Me resulta difícil añadir algo que anime a usarlo más que lo que ya escribí en la historia anterior. Seguramente da igual lo que yo diga. No entiendo cómo se pueden dirigir proyectos de software ignorando esta información, pero es lo que ocurre habitualmente. Lo único que puedo decir es que el manual resume en cincuenta páginas la chicha de varios gruesos libros con lo mejor que se ha escrito sobre calidad de código. Así que a quienes sepan apreciarlo: ¡que lo disfrutéis! :-)

Se mantiene el canon

En España ésta ha sido la semana del canon. El Partido Popular cambió por sorpresa su actitud durante la tramitación de la "Ley de Impulso de la Sociedad de la Información" (LISI) y apoyó una enmienda presentada por Jordi Guillot, senador de ICV, para instar al gobierno a que elimine el canon sobre soportes digitales, precisamente cuando se anuncian las nuevas tarifas. Aunque la enmienda prosperó en el senado, con la única oposición del partido del gobierno, ha sido rechazada de vuelta a la cámara baja por los votos de PSOE, IU, CIU y CHA, y las abstenciones de BNG, PNV y ERC. Existen rumores de que podría estar decidida la reforma o eliminación del canon a medio plazo , pero lo cierto es que empezaremos el año con el canon extendido a móviles y discos duros, y sólo ligeramente rebajado en DVDs que actualmente suponen ¡más de la mitad de su precio!

El sabor de boca que queda es amargo. No hay que ser demasiado perspicaz para deducir que el PP tiene la vista fija en las elecciones al parlamento de dentro de tres meses y, como sus detractores se han encargado de recordarnos insistentemente, no hicieron nada durante los no tan lejanos ocho años de gobierno de Aznar. Ni siquiera quedan claras sus intenciones actuales, pues Rajoy, que habla de crear una "agencia de la propiedad intelectual" con no se sabe qué atribuciones, habla del canon como un "castigo preventivo" (lo que quiere decir que piensa que se fundamenta en un hecho ilegal) y el mismo senador de ICV que presentó la enmienda considera ilegales las descargas de Internet y posible detenerlas mediante "medios tecnológicos", como se puede leer en la entrevista enlazada al principio.

Y esos lumbreras eran nuestra esperanza de que se eliminase el mangoneo. El PSOE y ahora también IU han dado su apoyo explícito al canon y eso es lo que el PP ha conseguido dejar en evidencia. Quizás no contasen con conseguir los votos para ellos, aunque pueden quitárselos a sus contrincantes. En cualquier caso el hecho de que el PP lo haya provocado no quita que sea la puñetera verdad. Los partidos nacionales que se llaman de izquierda están a favor de mantener este cachondeo en contra de la voluntad y los intereses de la mayoría. Por cierto, que el otro PP, el Partido Pirata, el único que había prometido arreglar de verdad esta situación, no ha podido presentarse a las elecciones gracias a la ley de paridad, que exige a los partidos políticos tener un determinado número de mujeres en las listas. Ya podemos presumir de democracia.

Los políticos siguen ostentando una abismal ignorancia sobre esa "sociedad de la información" que pretenden impulsar con leyes. Quizás sea una cuestión de edad, de que son de otro ramo o que realmente no les interesa lo más mínimo. Seguimos con la banda ancha más lenta y cara de los países de nuestro entorno. Seguimos con sueldos en el sector tecnológico que no llegan a la mitad de nuestros vecinos. Y como sobra el dinero, seguimos trasvasando más de cien millones anuales al sector "cultural" para que sigan sacando "operaciones triunfo" y "misiones en Marbella". Las fábricas de discos cerraron y nuestros representantes hacen leyes para hacer como que arreglan lo que en realidad están jodiendo.

No uséis el Translation Manager de Delphi

Hace ya meses contaba que la herramienta de traducción de Delphi tiene algunas rarezas. Ahora, con bastante más experiencia con ella, lo puedo decir más claro: no la uséis. Es básicamente inútil en cuanto el proyecto se complica mínimamente. Tiene bugs antiguos y nadie pone más simpelemente porque no la usa nadie en serio. Por ahí hay varias herramientas de terceros. Sisulizer parece tener buena fama. Helicon a mí no me ha convencido. Pero desde luego cualquier cosa menos usar el Translation Manager de las @#€$%&!!!

La opción que terminamos por usar es procesar manualmente los ficheros DFM. Las cadenas del código supongo que las tenéis bien ordenaditas desde el principio. ¿Verdad que sí? Los DFM son otra historia, pero el proceso no es disparatadamente difícil. Classes.pas incluye en ObjectTextTo... (¿binary o resource? nunca me acuerdo) el parser oficial del formato DFM. Si no os queréis calentar la cabeza: Sisulizer parece buena opción.

Lenguajes de nicho

En el planea de ThoughtWorks, la empresa de MartinFowler :-) me llamó primero la atención este artículo sobre backups automáticos de MySQL, que quizás me venga bien para evitar sustos en el alojamiento como los recientes. Después vi otro artículo sobre si es bueno ser un programador de un lenguaje de programación "de nicho".

Delphi está atravesando una época delicada, con CodeGear sólo segregada nominalmente de Borland, que sigue siendo la empresa matriz. En esta entrevista Jim Douglas, CEO de CodeGear, cuenta que la intención sigue siendo vender CodeGear a un inversor ajeno a Borland. También un detalle interesante: que están montando un sistema de venta directa, sin tener que pasar por los canales de distribución de Borland.

En cualquier caso, a pesar de las interesantes perspectivas de futuro, Delphi podría considerarse como un lenguaje de nicho y se le aplicarían las reflexiones que Jay Fields, el autor del artículo, hace sobre su reciente carrera con Ruby. Dando por sabidas las ventajas, habla de las desventajas:

  • Quedas limitado en tus opciones de conseguir un empleo. Oigo que hay empresas que no consiguen programadores. Pero la situación no es halagüeña para los candidatos. Muchos de los proyectos son mantenimientos de programas inmantenibles. Hay pocos proyectos nuevos y en general poca calidad en los procesos de programación.
  • Hay poca gente de la que aprender. Creo que este punto no es tan aplicable a Delphi. Aunque ahora esté en horas bajas, hay una cantidad enorme de información en Internet. Pero sí que es probable que los programadores más talentosos haya emigrado en busca de mejores perspectivas.
  • Mala fama. Esto es totalmente aplicable. Aunque todos los lenguajes tienen detractores, es más fácil recibir palos cuando estás en desventaja numérica. A los lenguajes menos extendidos no se los considera aptos para "el entorno empresarial" y a sus programadores se los ve como indisciplinados. Los tópicos, a menudo falsos, se convierten en coletillas comunes.
  • Cuando hay más gente se suelen estandarizar las buenas prácticas. Bueno, esto francamente no me parece cierto. Por el contrario, las empresas que adoptan buenas prácticas en el proceso de programación (no en el proceso burocrático) van contracorriente y no es raro que también escojan lenguajes menos populares. Desgraciadamente suelen buscar también la última moda :-)
  • Limitación de proveedores. En esta faceta Delphi se beneficia de su historia. Hay productos y alternativas, incluso a compilador y entorno, aunque no para el conjunto.

Alojamiento accidentado

Los últimos días, debe haber sido casi una semana, el alojamiento ha vuelto a dar problemas. Después de una actualización que arrojó un fallo, dejó de arrancar. El servicio técnico ha ido arreglando los sucesivos problemas con seguridad, pero lentillos. Tuvieron que recurrir a SWSoft, los autores de Virtuozzo, que tampoco daban con el fallo. Les dije que reinstalaran si eso iba a arreglaro, mientras me pudiesen dar los ficheros antiguos, por ejemplo la base de datos.

Resultó después que la Debian 3 reinstalada era incapaz de actualizarse, ni hacia Debian 4, ni pillar las actualizaciones de seguridad o instalar programas nuevos. Así que les tuve que pedir cambio a Debian 4. Finalmente ha estado cayéndose por un problema de configuración. Entre cada modificación, a veces me pedían confirmaciones un poco redundantes, que sumaban unas horitas más. El correo tuvo que dar la nota también. La configuración por defecto tiene deshabilitado el correo de Internet. Como no tengo ni idea de Sendmail, lo cambié por Exim, que con dpkg-reconfigure te saca un cómodo asistente. También me tuve que asegurar que estaba todo el soft necesario, como php, apache2... y mysql. Entonces vino otra papeleta. No tenía el backup de la base de datos, sino el directorio /var/lib/mysql. Por suerte, después de instalar en casa una Debian testing (que debe tener la misma versión del difunto sistema) y copiar los ficheros a pelo, pude arrancar la base de datos (adivinando la contraseña anterior) y hacer un mysqldump que acabo de restaurar aquí. Después sólo quedaba activar el mod_rewrite y... ¡vaya rollo! Pero aquí está en marcha otra vez.

En fin, esta vez me aseguraré de hacer copias de seguridad regulares. Si hace falta lo meto en el cron y me mando un bz2 por correo todos los días.

Distribuir contenido