martes, 2 de junio de 2009

HAL y la burocracia (V - las comillas)

Como advertíamos ayer, por los pequeños detalles merodea el diabólico encantamiento. Para desenmascararlo, vamos a realizar unos pocos experimentos.

En primer lugar, crearemos un variable y le daremos como valor una cadena:

ESCUDERO='Sancho Panza'

Nótese que las comillas son aquí necesarias. De no haberlas puesto, el espacio, un carácter especial en la lengua de HAL (el delimitador que sirve, por ejemplo, para determinar donde termina una orden y empiezan sus argumentos) hubiese sido interpretado por HAL como un separador. Más exactamente, si hubiésemos escrito:

ESCUDERO=Sancho Panza

HAL hubiese creado la variable ESCUDERO con el valor Sancho y hubiese tratado de ejecutar la inexistente orden Panza, con el consabido resultado de command not found. Ni siquiera la variable ESCUDERO hubiese retenido su valor, Sancho, porque, como sabemos desde hace mucho, la definición de variables en la misma línea y justo delante de una orden sólo afecta a la ejecución de esa orden.

Por tanto, las comillas en la anterior definición tienen una función importantísima, permitir que el espacio se interprete literalmente y no como un signo con un valor sintáctico especial. Lo que, en ese ejemplo concreto, implica que el valor de la variable ESCUDERO será Sancho Panza (espacio incluido), como podemos comprobar con un simple:

echo $ESCUDERO

que devuelve:

Sancho Panza

¿Hubiese sido diferente utilizar dobles comillas en lugar de comillas simples?

Lo probamos:

CABALLERO="Don Quijote"
echo $CABALLERO

Que devuelve, de forma semejante:

Don Quijote

Parece, pues, que no hay ninguna diferencia entre las comillas simples y las dobles comillas, que es cosa más de gusto que de gramática. Pero eso, justamente, es lo que quieren que creamos los pérfidos encantadores. De hecho, nosotros hemos utilizado hasta ahora ambos tipos de comillas sin mayor cuestionamiento. Pero las apariencias engañan. Veámoslo:

echo 'El compañero de $CABALLERO es $ESCUDERO'

produce:

El compañero de $CABALLERO es $ESCUDERO

Es algo que deberíamos haber esperado. Las comillas preservan también aquí el significado literal del carácter '$' y evitan que se interprete como un signo sintáctico especial, a saber, el de proporcionar el valor de la variable que le sigue.

Sin embargo,

echo "El compañero de $CABALLERO es $ESCUDERO"

devuelve, sorprendentemente:

El compañero de Don Quijote es Sancho Panza

La conclusión de nuestro experimento parece obvia, las comillas simples son rejas más seguras que las dobles. En general, de las comillas simples ningún carácter se evade de ser interpretado literalmente, mientras que hay caracteres especiales que no se doblegarán a las comillas dobles y seguirán exigiendo ser interpretados como tales signos sintácticos especiales. Entre estos pocos signos que han conseguido la prevalencia de su característica identidad sintáctica está nuestro querido '$'.

Lo que tan interesante conocimiento implica para el código propuesto al final del día pasado es que pone a las claras el origen de su error. Recordemos cuál era el código:

sed -e 's/ALUMNO/$ALUMNO_OUTPUT/' \
-e 's/CURSO/$CURSO_OUTPUT/' \
-e 's/OBJETIVOS/\\input{1-ge-objetivos}/' \
-e 's/CONTENIDOS/\\input{1-ge-minimos}/' $PLANTILLA > Sancho-Panza.tex

Las dos primeras expresiones de la orden sed contienen el signo especial '$'. Ahora bien, la expansión del valor de las variables ALUMNO_OUTPUT y CURSO_OUTPUT no se producirá, puesto que '$' se interpretará literalmente. Acabaremos con un fichero Sancho-Panza.tex con las líneas:

\begin{datosAlumno}
Alumno: $ALUMNO_OUTPUT
Curso: $CURSO_OUTPUT
\end{datosAlumno}

La solución, tras lo aprendido hoy, es bien simple, utilizar dobles comillas en las líneas díscolas:

sed -e "s/ALUMNO/$ALUMNO_OUTPUT/" \
-e "s/CURSO/$CURSO_OUTPUT/" \
-e 's/OBJETIVOS/\\input{1-ge-objetivos}/' \
-e 's/CONTENIDOS/\\input{1-ge-minimos}/' $PLANTILLA > Sancho-Panza.tex

Un lector espabilado podría imaginar una solución incluso más sencilla. Ya que las comillas esconden tantas triquiñuelas, ¿por qué no suprimirlas directamente?:

sed -e s/ALUMNO/$ALUMNO_OUTPUT/ \
-e s/CURSO/$CURSO_OUTPUT/ \
...

Desgraciadamente, no funcionaría, aunque sí funcionaría la siguiente solución:

sed -e s/ALUMNO/"$ALUMNO_OUTPUT"/ \
-e s/CURSO/"$CURSO_OUTPUT"/ \
...

Dejamos como ejercicio para el lector la experimentación y comprensión de las causas del fracaso y el éxito de las dos últimas propuestas.

Resumen

  • Las comillas simples permiten que todos los caracteres especiales de la lengua de HAL encerrados en ellas se interpreten literalmente.

  • Las comillas dobles hacen que casi todos los caracteres especiales de la lengua de HAL se interpreten literalmente, salvo algunos pocos (en especial, el carácter '$'), que seguirán manteniendo su peculiar función sintáctica.

No hay comentarios:

Publicar un comentario