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.

Frustrante

Desde Noviembre del año pasado estoy programando de a poquitos y muy lentamente un blog para mis fotos. Se está volviendo una experiencia frustrante porque quiero terminarlo ya. Pensé que podría avanzarlo unos 15 o 30 minutos libres que tuviese al día como lo hice con mi video One Year, One Second Every Day, pero estoy aprendiendo que es distinto editar videos que programar. Este último requiere más tiempo y mayor concentración. Cuando ya recordé dónde estaba y he planeado en mi cabeza cómo voy a programar lo que necesito, Ding! se acabó el tiempo, hora de hacer otra cosa. No es como cuando editaba los videos, podía continuarlo con facilidad. O dejar la máquina procesando, lo que producía avances en el proyecto. Para programar requiero una cantidad mayor de tiempo ininterrumpido.

Se está volviendo muy frustrante. Quiero tenerlo listo ya, quiero subir y publicar mis fotos. Tengo varias ideas por implementar, features, etc. pero ni siquiera he terminado lo básico. Es más, frecuentemente programo algo y luego lo voy refinando, así que lo que tengo avanzado no es el código final, hay cosas por pulir, algunas funciones feas que, debido a la fragmentación de tiempo, ni siquiera estoy seguro de cómo funcionan y no quiero ni tocarlas ni cambiarlas a pesar que, hey, creo que preferíria reducirle el ancho a las imágenes. Lo intenté y todo se desarmó. Oops, a regresarlo como estaba. Epa, no está generando bien las cachés. ¿Por qué? Pero sólo tengo 30 minutos y tenía planeado implementar otra cosa. Lo voy a dejar allí y luego veo por qué. Pero me incomoda dejarlo sin resolver.

Y… se está volviendo muy frustrante.

Empecé a considerar la idea de volver a intentar usar WordPress y usar mi función que arma bonito las imágenes como un plugin, pero recordé que quiero también publicar en inglés y español. Y que tendría que armar un theme con el diseño que tengo ahora. Luego descubrí Koken que se ve absolutamente genial — en serio, es asombroso — pero recordé otra vez: English and Spanish. Y usa un lenguaje propio para templates. Y quizás el tiempo que me tarde implementando mi blog tal como lo quiero con Koken sea el mismo que si continúo con lo que ya tengo.

Frustrante.

jwzhacks

Ya que estamos con la onda retro, hacía tiempo que no visitaba la página de hacks de jwz. Hay algunas cositas nuevas por allí. Un día de estos voy a publicar todos esos scripts pequeños que tengo regados por allí. Siempre pienso que sólo son útiles para mí, pero seguramente otros los encontrarán interesantes aunque sea como ejemplos o puntos de partida. Por cierto, nunca encontré el easter egg de la portada de jwz.

Complicación innecesaria

Los feeds RSS de Drawr (un website de dibujo japonés) muestran sus imágenes reducidas a 500 pixels, pero yo quería verlos con las imágenes a tamaño completo.

Luego de escribir gran parte de un script usando Ruby, Mechanize y Nokogiri, me topé con el problema que el feed está mal formado y eso no le gusta a Nokogiri. Pensé en usar expresiones regulares, como en los viejos tiempos, para sacar los datos de cada item y me comenzó a tomar más tiempo.

Tras analizar el problema nuevamente, me di cuenta que estaba tratando de resolverlo de la manera más complicada posible: hacer parse del feed RSS y armar uno nuevo sólo para cambiar la URL de la imagen, de “imagen_500.jpg” a “imagen.jpg”.

La solución, quizás ya obvia para ustedes, fue tomar el feed RSS como una gran cadena de texto y hacer un search and replace para eliminar la cadena “_500”. Listo. En menos de un minuto. Creo que me estoy oxidando.

Descargando trailers de Filmtrailer

Filmtrailer era uno de los podcasts de iTunes a los que estuve suscrito. La teoría es que iTunes descarga los podcasts automáticamente y los tiene listos para sincronizarlos al iPhone.

En la práctica me topé con varios detalles. No puedes decirle a iTunes una hora específica cuándo descargar y lo hacía en horario de trabajo, mi iPhone de 8Gb se llenaba rápidamente, la sincronización era lenta, iTunes es lento, etc.

Recientemente recordé Filmtrailer y como ya no quiero usar iTunes, hice un script de Ruby que descarga nuevos trailers de la misma fuente. Una tarea de cron lo ejecuta a las cuatro de la mañana.

Pueden descargar el script aquí. Requiere wget y las gemas Mechanize y Nokogiri. En realidad podría reemplazarse Mechanize con open-uri, pero lo programé sobre la base de un script anterior más complicado y quedó así.

A single line of code sends readers into a labyrinth →

10 PRINT CHR$ (205.5 + RND (1)); : GOTO 10, a new book collaboratively written by 10 authors, takes a single line of code—inscribed in the book’s mouthful of a title—and explodes it.

That one line, a seemingly clumsy scrap of BASIC, generates a fascinatingly complicated maze on a Commodore 64. Run the little program on an emulator—or on an actual Commodore 64, if you happen to have one collecting dust in your basement—and a work of art unfolds before your very eyes, as the screen slowly fills up in a mesmerizing fashion.

Puedes descargar el libro en formato PDF gratuitamente en 10print.org

RubyMotion: Ruby for iOS →

¡Qué noticia tan emocionante! RubyMotion te permite crear aplicaciones para iOS (iPhone, iPad) usando Ruby. Tienes acceso a todas las APIs, es compilado (el ejecutable es veloz, veloz), hay una REPL alucinante y todo sobre la línea de comandos. Esto es del mismo desarrollador de MacRuby, garantía de un producto sólido.

Por el momento miro de lejos la posibilidad de hacer desarrollos para iOS, pero si algún día me animo, de hecho incluyo en el presupuesto una licencia.

Diciembre 27, 2010

Me desperté a las 7:11. Nestor ya me había escrito antes de las 7:00, vuelta al trabajo.

Detesto Smarty. Como tiene su propio parser no es posible usar una variable como índice de un hash, tuve que crear una variable extra, lo cual es horrible y feo. Hacer algo sencillo me tomó más tiempo del necesario por ese pequeño detalle. Paciencia. La labor de limpieza y reingeniería de todo el código me va a tomar tiempo, pues paralelamente hay que ir avanzando con los pedidos.

Quiero ver Tron: Legacy; ya está en cartelera, pero sólo el UVK lo tiene subtitulado en la sala 3D (en Cinerama todas sus funciones son dobladas). No tengo interés en verla en 3D y encima es más caro. Grr. De todos modos no me la voy a perder.

Acabo de descubrir el tag {php} de Smarty, hah. Ok, eso va a hacer el desarrollo más tolerable mientras desaparezco Smarty de aquí. Estoy pensando si hay alguna manera de automatizar los cambios. Por lo pronto mi poderoso aliado es siempre bufdo de Vim.

No recordaba qué tan inconsistente es PHP. Para escapar las variables SQL con MySQL, la función se llama mysql_real_escape_string. Con PostgreSQL es pg_escape_string. mysql_real_escape_string toma la conexión como primer parámetro, mientras que pg_escape_string lo toma como segundo.
A la primera oportunidad migro todo esto a Ruby on Rails. Es inhumano programar así. :)

Estuve de pasada por Zeta Bookstore ¡y no había la sección de Phantom Music! ¿Ahora dónde puedo comprar CDs originales? :(