Lo que no me gusta de Laravel

He estado leyendo, probando y viendo un poco de cerca Laravel, buscando agilizar los desarrollos que hacemos en Nodos.

Estas son algunas cosas que no me han gustado de Laravel. Quizás en algunas esté equivocado, dado que sólo he construido algo pequeño con el framework para tener un hands-on experience y no tengo un conocimiento a profundidad de éste. Corríjanme si me equivoco.

NOTA: Al momento que escribo esto, la versión más reciente de Laravel es 5.6.

La magia

Este es un código de ejemplo copiado del manual de Laravel acerca de validación:

/**
 * Store a new blog post.
 *
 * @param  Request  $request
 * @return Response
 */
public function store(Request $request)
{
    $validatedData = $request->validate([
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ]);

    // The blog post is valid...
}

Lo que se puede ver es que hay una llamada a $request->validate().

Lo que no se ve es que si validate() encuentra contenido inválido, arroja una Excepción y se redirige automáticamente a la página anterior (con toda otra funcionalidad detrás de cámaras para preparar los errores y la persistencia de los valores antiguos).

Este comportamiento “mágico” no es visible ni intuitivo en el código, violando el Principle of Least Surprise. Solamente alguien con conocimientos de Laravel sabe lo que va a suceder.

Por otro lado, los Exceptions están siendo usados para controlar el flujo de la aplicación, lo cual es una mala práctica. Citando a Philip Brown:

An exception is basically an exceptional circumstance that is often unrecoverable from. This means something went wrong and we can’t proceed with running the application because the program is unable to carry on executing.

For example, I see a lot of code where the developer is using exceptions to control the flow of logic.

Exceptions should only be used in exceptional circumstances and therefore should be used sparingly.

Los famosos “Façades”

Mathias Verraes lo sabe decir mejor:

Laravel’s Facades have global state, which is precisely the thing you *shouldn’t* do. It is bad design and should be deprecated. They are nothing more than an elaborate $_GLOBALS.
(And they are a misnomer, as they are not Facades in the OOP meaning.)

Los formularios

Zend Framework 2 y 3 tienen Forms, que son colecciones de Form Elements con validación. Puedes crear nuevas clases de Form Elements como por ejemplo, “DNI” que incluye validadores, filtros, atributos, etc.
Laravel no tiene un concepto similar, estas funcionalidades están dispersas. Menos que eso, los helpers para renderizar los elementos de formulario fueron retirados del framework. No hay una base sobre la cual crear elementos reutilizables.

Service Container y PSR-11

Debido a requerimientos de clientes, en Nodos seguiremos usando tanto Zend Framework como Laravel. Revisando la interoperabilidad de Laravel en relación a su Service Container, veo que no se ajusta al PSR-11 — tampoco al ahora obsoleto container-interop.

Quizás tengamos que usar zend-servicemanager o algún otro Container PSR-11 para los Layers framework-agnostic.

Coda

Sobre el tema de la magia, cabe mencionar lo obvio: todo framework, por definición, trae consigo cierta medida de magia. Desde Rails, esto viene siendo un debate; y como ex-Rails developer, tengo tolerancia a cierta medida de magia pero ahora estoy gravitando más hacia lo explícito.

Hay “magia buena” (e.g. convention-over-configuration) y “magia mala” (e.g. leaky abstractions). La primera es aceptable, la segunda no.

Es mi sentir (y meramente mi opinión personal) que Laravel sacrifica mucho por darle prioridad al aspecto “beautiful code” y el “developer as an Web Artisan.” Para que Laravel pueda ser más interoperativo y desacoplado tendría que cambiar mucho estructuralmente, pero dudo que formen parte de las metas de Taylor Otwell. Mientras no pretenda convertirse en omakase, estamos bien.

Para equilibrar la balanza, en un próximo post haré una lista de las cosas que me gustan de Laravel.

Diciembre 28, 2010

Me desperté a las 6:50am, leí mi devocional en la cama y luego Dune. Me quedé nuevamente dormido hasta las 8:00am, grr.

Estoy escuchando el nuevo álbum de Gorillaz, The Fall, creado en su mayoría en un iPad. Revolving Doors es pegajosa, ya perdí la cuenta de cuántas veces la vengo repitiendo.

Sigo con el trabajo. Por primera vez he escrito documentación para Deborah, mi librería de abstracción de Base de Datos en PHP. Estuve buscando alguna clase o librería para tener algo más parecido al ActiveRecord de Rails, pero el tiempo nos gana. Al parecer las mejoras al código existente se van a dar lentamente. Tengo que tener pacieeeencia.

No perdamos el enfoque

Este es un extracto modificado y extendido de un, eh, desquite escrito en otro lado que no viene al caso mencionar. Es una lección que he estado aprendiendo últimamente y que estoy viendo repetirse a menudo y me encuentro a mí mismo diciendo la misma frase: “No hay que perder el enfoque.”

Muchas personas dicen entonces que eso no es “el standard de la industria,” o parte de las “mejores prácticas.” Y en repetidas veces esas cosas nos llevan erradamente a perseguir procedimientos o caminos en lugar de concentrarnos en resolver el problema.

“Hay que usar la mejor herramienta para el trabajo,” dice la sugerencia. Pero si tengo un apuro en abrir el case de mi computadora en una emergencia y lo único que tengo a la mano es un cuchillo y no un destornillador estrella, ¿adivinen qué es lo que voy a usar?

No, tonto. Tienes que conseguirte el destornillador estrella. Es el standard. Nos regimos y seguimos reglas sin entender el verdadero significado de por qué han sido definidas y la razón de su existencia.

Un extremo claro son los hospitales donde no te pueden atender a menos que llenes antes un formulario, porque “ese es el procedimiento.” Procedimientos, primero — el ser humano después. Se pierde el enfoque y la claridez de lo que se está haciendo, el objetivo que se quiere lograr; en el caso de un hospital, brindar atención médica a las personas.

Por supuesto, es otro gigantesco error irnos al otro extremo y decir que las reglas y procedimientos no sirven para nada e ignorarlos olímpicamente. Se llaman “mejores prácticas” por un motivo válido. Se establecen procedimientos por ciertas razones. Lo importante es entender y discernir el propósito de cada procedimiento y hacer lo correcto en cada caso.

Cuando perdemos el enfoque todo se viene abajo. Pensamos que el numerito obtenido de un examen determina la proficiencia de una persona en dicho curso y no es así. Pensamos equivocadamente que se puede representar la aptitud o inteligencia de una persona con un solo número y es una tontería.
Alabamos una buena nota y castigamos una mala nota sin discernir que es una mera figura, una representación pálida. Alguien con una plagia o una memoria fotográfica puede transcribir, palabra por palabra, lo que tiene y obtener una buena nota. Alguien que ha estudiado duro, pero que al final se llenó de nervios por la importancia que tiene pasar este curso obtiene al final una mala nota. No rindió al 100% de sus habilidades, no por su conocimiento, sino por un factor externo. Y no podemos decir “No sabe, no estudió, la nota baja lo demuestra,” porque es un estúpido escalar que no representa nada.

Y entonces aparecen los que se van al otro extremo y puntillean, ¿Significa eso que debemos de eliminar todas las notas? ¿Que el sistema no sirve y que no debemos basarnos en ello? Que no, carambas. Es necesario tener un punto de referencia, una manera de medir el aprendizaje — pero tomémoslo como tal, como una referencia.
“Veo que sus notas de colegio, estimado entrevistado, son deficientes. Es usted, pues, un bruto y no lo necesitamos en nuestra empresa.”
Ajá. El divorcio de mis padres durante esa época no tuvo nada que ver. ¿Qué tal si me hace un par de preguntas o me toma un examen de aptitud y vemos si, en la práctica, soy realmente útil para su empresa? ¿O si mira los proyectos que he estado haciendo?

Oh no, papelito manda.

El año pasado cuando entrevisté a personas buscando un programador me importó un comino o dos si venían vestidos en terno o en chancletas, si habían estudiado en La Católica o con su primo Juancito. A todos les hice las mismas preguntas y ninguno, NINGUNO, pudo completarme una tarea de programación. Mi elección se hizo en base a la forma cómo intentaron razonar para salir del apuro, porque lo que buscaba es alguien que sepa razonar, no que tenga las siglas “Ing.” delante de su nombre, sino alguien con aptitud, alguien con potencial y capacidad. No alguien que sepa “Java” y “PHP” porque nuestra industria se mueve tan rápido que “Java” y “PHP” van a ser obsoletos o desplazados de todas maneras.

Debemos de detenernos un momento a pensar y observar si estamos siguiendo reglas ciegamente o estamos usando la razón. Hace años atrás renuncié a un buen trabajo en Lima por la sencilla razón que ese trabajo se convirtió en todo y llegué al límite de querer abandonar por completo a mi Señor.
La incomprensión de personas no creyentes no me sorprendió — lo que me sorprendió fue la incomprensión de creyentes que consideraron “tonta” y absurda mi decisión. “¿Por qué un creyente no puede ser rico?” preguntó una creyente y es como si no hubiese entendido nada en toda su vida.
Su patrón de éxito estaba marcado por lo que el mundo dice y no por lo que Dios dice. Nuestra mira y nuestra meta es otra. Es tan desorientado como decir que lo más importante en el colegio es haber llenado la mayor cantidad de álbumes de figuritas que todos los demás en la historia del colegio. “¿Y por qué un alumno no puede tener la mayor cantidad posible de álbumes?”

Mi conclusión es: no debemos perder el enfoque del por qué de las cosas, del motivo y razón detrás de cada standard, cada regla, costumbre o procedimiento. No obedezcamos ciegamente las cosas porque “así son,” “siempre han sido así” y “los demás también lo hacen” sino usemos el razonamiento y la sabiduría para hacer siempre lo Correcto.

(Y lo Correcto en reiteradas ocasiones rompe las reglas.)

Un website cristiano hecho en Django

Tabo me envió por mail (¡gracias!) este post de Luke Plant sobre sus apreciaciones de tiempo y velocidad de desarrollo ilustradas con un proyecto suyo hecho en Django, que es un website para campamentos cristianos.
Es realmente interesante y me he descargado el código fuente para leerlo, ya que siempre se puede aprender muchas cosas de otra persona.

Aparte de Retrazos, otro conejillo de indias para mi aprendizaje de Ruby on Rails es Via7, un website que hice hace tiempo para jóvenes creyentes. Originalmente en PHP, Via7 era un gran hack a un phpBB que quedó en el descuido al expirar el dominio.

Espero que sea muy pronto poder tener el mismo gusto de Luke de anunciarles la finalización del proyecto. Aunque todos sabemos que la web de una comunidad nunca termina. ;)

Mejorando mi carrera

Una de las metas más relevantes que me he trazado para este año 2006 es “He mejorado en mi carrera, soy más veloz, más eficiente.” A principios de año me sentí estancado, como si hubiese llegado a cierto punto donde mis conocimientos me son suficientes para mi trabajo y todos los proyectos que veía eran más de lo mismo y nada nuevo, ningún reto, a menos que yo mismo me imponga uno para mejorar procesos. Eso es algo que me ha venido preocupando.
He estado intentando aprender cosas nuevas (PEAR DataObjects, AJAX), pero sentía, como le contaba a mis padres, que todos alrededor mío siguen avanzando y yo me estoy quedando atrás.

He tenido muchas sorpresas con lo que el Señor me ha estado enseñando con esta meta trazada, todo por diversos factores como, por ejemplo, mis ideas prehistóricas de cómo debo hacer las cosas o la falta de interactuar más con otras personas, colegas, amis linuxeros.
Voy a darles una vista general de las cosas que me han venido aconteciendo últimamente. Todo esto ha venido sucedido desde Enero y entre punto y punto hay a veces varias semanas o meses de separación. Algunas se solapan entre sí. Bueno, empecemos:

– Primeramente como mencioné ambiguamente en un post atrás, Tabo me habló de Python y Django y ese solo consejo me abrió muchas posibilidades. Ya entendí que PHP no es el futuro, a menos que reescriban todo el lenguaje desde cero y reinventen Python o Ruby.

– Luego encontré este fabuloso blog de Kathy Sierra junto con este todavía más fabuloso post acerca de la neurogénesis y una interesante conclusión: “Aprender cura el cerebro.”

– Me puse a aprender Python y Django simultáneamente.

– Hablando con Antonio acerca de PHP5, Ruby y un poco de Python, llegué a una conclusión importante que me dio mucha confianza: que puedo aprender cualquier cosa. Al descubrir esto me dí cuenta que una parte de mí dejó de creer que tengo la capacidad de aprender, un tipo de “ya estoy muy viejo para aprender tantas cosas,” lo cual me parece absurdo. ¿Desde cuándo he empezado a pensar así y por qué?

– Cuando regresé de Lima volví a visitar el blog de Kathy (tengo mi lector RSS desactivado por motivos productivescos) y me encontré con este post acerca de cómo volverse un experto en cualquier rama. Menciona la diferencia entre expertos, novatos y mediocres, pero lo más interesante es este párrafo que se los traduzco:
“Oh si, acerca de esa cosa de que nunca es tarde… la mayoría de nosotros puede despedirse de la medalla Olímpica de patinaje sobre hielo. Y a mis 5′ 4”, mi carrera de basketball no tiene probablemente esperanzas. Pero piensa en esto… la actriz Geena Davis casi calificó para el equipo Olímpico de tiro con arco de Estados Unidos en un deporte que ella tomó a la edad de 40, menos de tres años antes de las calificaciones Olímpicas.

– Luego Droper compartió este post que me gustó mucho sobre Matemáticas para Programadores.

– De ese post salté a este otro enlace que me pareció todavía más fascinante y, a mitad del artículo pensé “¿Desde cuándo las matemáticas me parecen fascinantes?” Siempre le he tenido miedo a las matemáticas y he tenido muchas dificultades toda mi vida.

– Recordé entonces a mi hermano que nunca fue bueno en matemáticas en el colegio. Cuando ingresó a Ingeniería Civil no se rindió ante la idea de tener que masticar matemáticas. Hoy le gustan las matemáticas y daba clases a los hijos de algunos creyentes en Covida. Creo que una de las cosas que lo inspiró fue Johnny Rico, el protagonista de Starship Troopers (el libro, la película no existe).
Al principio a Johnny le hacen un examen del cual los resultados son: “insuficiente entendimiento intuitivo de relaciones espaciales… insuficiente talento matemático… preparación matemática deficiente… tiempo de reacción adecuado… buena vista.” Como algo paralelo a toda la historia, uno ve a Johnny estudiando duro matemáticas, recibiendo tutoría de diversas personas y preocupándose por haber dejado sus libros en otra nave espacial.
Johnny dice “Matemáticas es trabajo duro y ocupa tu mente — y no duele aprender todo lo que puedas de ello, no importa en qué rango estés; todo lo que sea de importancia está fundado en matemáticas.”
He aprendido que esa última frase es muy cierta. Von Neumann se levantaría de su tumba y te comería el cerebro personalmente si te atreves siquiera a cuestionar eso.

– Mirando en el mismo website de Math a Day, llegué a este artículo y mientras lo leía pensaba, “Esta persona ha trabajado en Amazon, haciendo cosas realmente interesantes — ¿por qué yo no hago esas cosas?” y llegué a muchas conclusiones que todavía quiero terminar de meditar. Mas una de ellas es firme: Amazon usa mucha matemática brillante para funcionar.
El artículo trata acerca de practicar programación, como cuando uno practica pesas. No es algo que haces en tu trabajo diario, sino algo que debes hacer de manera separada, dedicada, aparte.
Si aprecias tu carrera, por favor lee ese artículo. La parte que más me llamó la atención es la siguiente:
De todas tus habilidades como programador, ¿cuáles de ellas podrían ser consideradas “intemporales”? Encáralo: la mayoría de tu conocimiento técnico tiene un tiempo de vida, una fecha de expiración.
[…] Lo que yo creo que encontrarás es que matemáticas, ciencias de la computación, escritura, y habilidades sociales son en su mayor parte intemporales, habilidades universales. Las tecnologías más específicas, lenguajes y protocolos eventualmente expiran, para ser reemplazadas por mejores alternativas.”

– En un momento dado me dí cuenta que, sin querer, estaba logrando cumplir esta meta que me había trazado. A diferencia de otras metas donde le pongo bastante empeño conciente, esta meta cayó por sí sola y las cosas se movieron “sin esfuerzo” de parte mía. Me dí cuenta que es el Señor quien estaba moviendo las circunstancias.

– Pasaron varias semanas y una noche decidí mirar Ruby y Rails y cambié mi rumbo. Quedé fascinado con el lenguaje Ruby y sigo aprendiendo desde entonces más de Ruby y Rails.

– De un momento a otro me dí cuenta que había crecido. Fue progresivo, y en un tiempo relativamente corto, pero mi vida ha dado muchos giros comparado a lo que “tenía” a principio de año.

– Una vez que estuve en Peruserver cogí por segunda vez un libro de matemáticas que hay en la biblioteca y Antonio me dijo, “Ya que tanto quieres aprender, ¿por qué no te metes a la universidad?”

– Sigo aprendiendo Ruby y Rails. He meditado seriamente la idea de meterme a la universidad, mas por ahora no siento la Voluntad del Señor por esa ruta; otras puertas se han estado abriendo por otra ruta que espero comentar en otro post. Eso no descarta que siga aprendiendo y creciendo por mi cuenta.
Gracias a Savre, voy a hacer averiguaciones para tomar cursos y llenar esas lagunas que tengo.

Y la vida continúa… :) No hay conclusión, no hay punch line. Esta es mi vida y siguen apareciendo oportunidades y puertas que se abren, puertas que se cierran, todo siempre interesante.

Belleza de código

La primera vez que leí acerca de “belleza” en programación fue en un escrito de Paul Graham. La segunda vez fue a Tabo haciendo referencia al evangelismo de belleza de David Heinemeier Hansson sobre Ruby y programación en general en el video de Snakes and Rubies.
Tengo otra idea muy familiar que, personalmente, conozco bajo el nombre de “elegancia.” Código que es “elegante” y soluciones “elegantes” a problemas complejos. En mi cerebro he catalogado “elegancia” y “belleza” como dos ideas no intercambiables. Ojo que esta es mi categorización personal, nada canónico:

“Belleza” de código es la diferencia motivacional que existe entre:

inicio = Time.now.beginning_of_day

y

$inicio = mktime (0, 0, 0, date (“m”), date (“d”), date (“Y”));

El primer código, en Ruby, es a todas luces guapísimo. :)

“Elegancia” es, en mi diccionario, algo que no tiene que ver mucho con cómo se ve el lenguaje, sino pasos ingeniosamente elaborados para la resolución de un problema de la mejor forma posible. El código no será necesariamente bello, pero la solución puede ser elegante.

PHP es, definitivamente, no bello — por decirlo de una manera agradable. Sin embargo, eso no le quita que podamos escribir código elegante en él.

Vamos con un ejemplo real.

Estoy actualmente trabajando en un proyecto sujeto a bastantes cambios estructurales. Escribí una función de búsqueda para cada uno de los tipos de registros que manejamos en base a ciertos criterios. Estas funciones devuelven un array con los resultados. Por ejemplo:

function actividades_buscar ($db, $vista, $localidad, $linea, $mes, $anyo, $pagina)

Esta función se llamaba desde un solo lugar inicialmente, luego conforme vinieron los cambios empecé a usarla en algo de cuatro lugares distintos del sistema. En el lugar original no había mucho problema en entender el código, ya que le alimentaba con variables recibidas por GET.
Sin embargo, en los otros lugares donde hacía búsquedas predefinidas (hardcoded) como que ya no era tan legible:

$resultados = actividades_buscar ($db, “general”, “0000000000”, -1, -1, -1, $pagina);

(Ough!)

Pero lo peor fue cuando el cliente decidió añadir más criterios de búsqueda… así que añadí un par de parámetros más a mi función y actualizar en todos los lados, pero oops! se me escapó en una parte y el cliente detectó el bug. Ok, a corregir.

Luego el cliente decidió añadir otro criterio más de búsqueda y ya me estaba doliendo (podría decir físicamente) cambiar en N-lados lo mismo y tener un código que era horrible. La gota que derramó el vaso fue cuando el cliente pidió que también se pudiesen ordenar los resultados por columnas y tenía que pasar un parámetro de ordenamiento a mi función de búsqueda quedandome con una definición de:

function actividades_buscar ($db, $vista, $localidad, $linea, $acciones, $mes, $anyo, $criteria, $mes_inicio, $anyo_inicio, $mes_fin, $anyo_fin,$sort, $pagina)

(Oh, la humanidad.)

Obviamente no iba a entender ni papa de qué cosa es qué aquí:

function actividades_buscar ($db, “regional”, “0000000000”, -1, -1, -1, -1, ”, -1, -1, -1, -1, ”, $pagina)

Este código era tan horrible que me dije “Es un asco. No puedo creer que esto exista.” No tenía tiempo para corregir eso, pero era tan horrible y tenía tanto miedo que me pidiesen otro cambio en esa parte que decidí dejar de lado todo y sentarme a reescribir todo eso.

La solución final fue pasar cada uno de los criterios de búsqueda en un array, y si no mencionamos un criterio, éste obtiene un valor por defecto sensible. Eso significó reducir la declaración de mi función a:

function actividades_buscar ($db, $params)

y llamar la función con solamente los parámetros necesarios de la siguiente manera mucho más legible y elegante:

$resultados = actividades_buscar ($db, array (
        ‘vista’ => ‘general’,
        ‘pagina’ => $pagina_actual,
   )
);

Ahora sí tengo paz. :)