considered harmful
while gets
if /Ruby/
end
end
Últimamente he estado programando en lenguajes que antes me parecían muy raros. Los primeros que aprendí fueron en orden: Pascal, C, C++, y Java (también Visual Basic pero todos tenemos algo que ocultar). Nunca me había metido a investigar la familia Perl, Python, Ruby y similares. Admito que después de despojarme de algunos esquemas mentales le he cogido el gusto, sobre todo a Python y Ruby. Son sumamente expresivos, tienen librerias de clases muy completas, y casi cualquier cosa se resuelve con muy poco código. El trabajo con cadenas de texto, que es la pesadilla de la programación en C, es una maravilla con estos lenguajes. Lo mismo para el trabajo con listas, con XML, y con un montón de cosas más. Probablemente para muchos programadores que empezaron su carrera con ellos sea lo más natural del mundo asignar paralelamente los elementos entre dos listas, así…
foo, bar = a, b # foo = a y bar = b
..pero en los lenguajes a los que yo estaba habituado esto era ciencia-ficción. ¿Y que me dicen de esta joya?
a,b = b,a # intercambiar los valores de a y b
Cuando yo estudiaba programación en la universidad la clásica función swap era como una especie de algoritmo fundamental, básico, todo el mundo tenía que saber como se hacía un swap.
tmp = a
a = b
b = tmp
Mi swap de toda la vida tirado por tierra 🙁
Los que vengan del mundo C como yo, sentirán la misma sensación de que nos estábamos complicando la vida sin necesidad. Sin embargo, después de todo me alegro de haber empezado por debajo, por los cimientos, siguiendo el camino natural de las cosas. Está claro que para inventar un Perl, un Python y un Ruby primero había que inventar un C. Además me imagino lo traumático que debe ser empezar a programar en uno de estos lenguajes; todo comodidades, todo facilidad para el programador, y luego tener que aprender C y C++, venga… a ocuparse de liberar la memoria, a cuidarse de los punteros a NULL, a declarar las variables como dios manda, a aprender lo que es un compilador dando el coñazo: «oye tú, que estás asignando un entero corto a un entero largo, si luego no funciona no es culpa mía», en fin…. que prefiero haber pasado por lo duro antes. Además, el haber pasado por estos lenguajes «incómodos» donde tienes menos facilidades, te ayuda a no caer en la tentación de utilizar características de los lenguajes «cómodos» que no son del todo deseables. Ese es el caso de la variable $_ de Perl, Python y Ruby ($_ es el nombre en Perl, en Python y Ruby es _ a secas, pero uso la notación de Perl para que sea más legible).
Esta variable, que se llama $_, que tú no la has declarado pero existe, que tú no le has asignado nada pero que tiene siempre un valor, que encima cambia constantemente sin que tú se lo ordenes, es el uno de los inventos más aberrados de la programación, incluso más que el goto. La susodicha variable almacena el valor de la última expresión evaluada. O sea que si escribo:
b = 5 + 6
justo después de ejecutarse la instrucción la variable $_ tiene el valor 11, al igual que b. Si llamo una función:
my_function()
$_ tendrá el valor retornado por la función aunque no se le haya asignado explícitamente. Además hay casos en los que el valor de esta variable es usado si no se especificamos otro explíctamente, como por ejemplo con print. Si se pone print «algo», por supuesto se imprimirá ese «algo», pero si se pone print a secas se imprimirá el valor que tenga $_ en se momento. Lo mismo pasa con la verificación de expresiones regulares. Tanto en Perl como en Ruby se puede comprobar si una cadena contiene una expresión regular de esta forma:
cadena =~ /expresionregular/
pero, si se pone /expresionregular/ a secas, se comprueba si $_ contiene la expresión regular.
Esta característica, cuya utilidad es más que dudosa, permite en cambio escribir verdaderos paradigmas de ilegibilidad. Como este…
while gets
if /Ruby/
print
end
end
Y ahora que me doy cuenta, el título del artículo en ralidad era «$_ considered harmful».