Random IRC quote :      <madalenasbuenas> me voy a pelar patatas

considered harmful

while gets
  if /Ruby/
    print
   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».

5 Comentarios para “considered harmful”

  1. Comment por Gabriel Gonzalez | 09/19/06 at 7:22 pm

    Desde mi punto de vista, todo es «harmful» si no conoces bien en el mundo en el que te mueves. Si, como comentas, vienes del mundo C sabras que, incluso gente con experiencia, hay ciertas composiciones que son realment inteligibles si no trabajas con ellas amenudo.

    Desde mi punto de vista el uso $_ es la expresion maxima de la utilidad y finalidad de los lenguajes estilo perl, implementar la maxima funcionalidad en el menor tiempo posible, lo que implica

  2. Comment por Rubén | 09/19/06 at 8:29 pm

    Hombre, yo sólo puedo dar mi opinión de haber usado $_ en el procesamiento y parseo de archivos, con Perl, y la verdad es que me fué útil. Pero bueno, supongo que en otras ocasiones pueda inducir a error, no sé. Mi experiencia en ese campo es bastante limitada.

  3. Comment por vmalvarez | 09/21/06 at 9:21 pm

    Para mi Perl y demás están de puta madre, hace poco no los conocía, pero he descubierto su potencial y la verdad es que se agradece tenerlos a mano para muchas cosas. Si se trata de hacerse un script «desechable», de esos que usas un día y nada más, no está mal usar $_ .Pero si lo que quieres es hacer en uno de estos lenguajes algun programa que luego tiene que ser mantenido y mejorado, mejor abstenerse de escribir cosas poco legibles. Los segundos que te ahorras escribiendo menos y usando $_, te los puedes ahorrar dentro de un mes cuando tengas que volver a leer tu código y entender lo que querías hacer. Esto no es que pase solo en este tipo de lenguajes, en todos se pueden hacer cosas muy guarras. ¿Por qué escribir esto…..?

    (x>y)?(funcion1):(funcion2)(param1, param2);

    Si se puede poner…

    if (x>y) {

    funcion1(param1,param2);

    }
    else {

    funcion2(param1,param2);

    }

    Hay que teclear más, pero queda claro para todo el mundo, incluso para el que no sabe C, pues con $_ pasa igual.

  4. Comment por svch0st | 09/24/06 at 5:14 pm

    Totalmente de acuerdo con Victor.
    Codigo legible vale por dos… (¿?¿)
    Vamos, que si te toca mantener una aplicacion escrita por un grupo de personas que además de sus diferentes formas de pensar, emplean formas «cortas» de sintaxis a mogollón al programar puede que acabes quierendo cortarte las venas…

  5. Comment por Lebrel | 09/25/06 at 12:23 pm

    La programación ofuscada esta bien para los concursos, pero sin más.

    De todas formas, tanto perl como python, C, etc… tienen sus «trucos» que por un lado ayudan a desarrollar el código más rápido y por el otro hacen más dificil su lectura; no por eso todos esos «trucos» tienen que ser aberraciones. Lo que realmente es una aberración es, la mayoría de las veces, el uso que se da a esos «trucos»; por ejemplo $_.

    S2

Se han cerrado los comentarios