Hola, soy Dani.

Soy un desarrollador de software y creador de contenido educativo sobre programación.

Me gustan los sistemas de software limpios y ordenados y me interesa la usabilidad y la accesibilidad. Me fascina poder crear experiencias simples y pensadas para seres humanos en primer lugar. Estoy ubicado en la zona de Madrid (España).

Estoy disponible como freelance o como consultor a partir de septiembre de 2022. Todavía esto está por desarrollar, pero si te interesa mucho, podemos ir hablando ya 🙂


Estoy intentando poner orden en los archivos de mi página web, pero mientras tanto puedes encontrar un historial en bruto de las cosas que he escrito aquí.

⬇️ ⬇️ ⬇️

  • He olvidado tomar pantallazo del mensaje de confirmación, pero lo importante es que he eliminado mi cuenta esta mañana. Por lo menos el proceso de confirmación es sosprendentemente corto para ser un producto de Facebook Meta.

    Nunca acepté los nuevos términos de uso entonces por otra parte hubiese sido cuestión de tiempo igualmente que se me hubiese bloqueado la cuenta.

    Pero en el fondo la razón por la que lo he hecho no tiene nada que ver con la privacidad. Es simplemente que he concluido que mirar los chats una vez al mes no es útil para nadie. «Ponerme al día» normalmente se acaba traduciendo por marcar como leídos cientos de mensajes viejos de grupos sin prestarle demasiada atención. Tampoco era útil para mis amigos, ya que ya fui informado varias veces de que al no leer los grupos, estoy bloqueando los checks azules que salen cuando todo el mundo lee un mensaje.

  • ¿Sabes cuando usas la doctrina «si funciona, no toques», pero aun así las cosas se rompen por arte de magia de un día para otro?

    Bundle tiene este problema a veces, que no he podido depurar pero que no es la primera vez que me ocurre: debido a que pueden coexistir múltiples versiones de una gema en simultáneo, a veces utilizar un shim (o sea, invocar rspec o rails en la consola sin más, sin especificar bundle exec ni usar el binstub) falla, porque no está usando la versión concreta de alguna dependencia.

    Después de actualizar unas dependencias en nuestro Gemfile, me empezó a salir este mensaje de error:

    /Users/danirod/.rbenv/versions/2.6.7/lib/ruby/gems/2.6.0/gems/bundler-2.2.17/lib/bundler/runtime.rb:302:in `check_for_activated_spec!': You have already activated rspec-support 3.10.3, but your Gemfile requires rspec-support 3.10.2. Prepending `bundle exec` to your command may solve this. (Gem::LoadError)

    Se soluciona usando bundle exec rspec en vez de rspec. No es que tenga fobia a escribir bundle exec antes de mis comandos, pero mi sentido común me dice que si día tras día, escribir rspec funciona, si de repente deja de funcionar de un día para otro, el problema no lo tengo yo. Por no ir, no me iba ni el binstub. O sea, bin/rspec también me da el mismo mensaje de error.

    A veces cuando me pasan estas cosas hago un pristine, o un cleanup. No piques: es una ruleta rusa. A veces se tira 15 minutos limpiando y reinstalando paquetes para luego seguir fallando al ejecutar. En esta ocasión, he optado por tirar una solución más rápida:

    gem uninstall rspec-support
    bundle install

    Si primero elimino todas las versiones de esta gema que hay en mi ordenador, y luego vuelvo a hacer bundle install, me deberá dejar una única versión instalada: la que pida el Gemfile. Me parece una solución aceptable. Esta es mi workstation, y no uso rbenv con software esencial (si tuviese software instalado desde Homebrew que esté escrito en Ruby, probablemente usaría el Ruby de Homebrew, no rbenv). A lo que quiero llegar es a que no pasa nada si elimino todas las versiones de un paquete y luego reinstalo.

  • El otro día respondí lo siguiente por nuestro Discord en un hilo [1] en el que se debatía si era 100% necesario escribir tests a la hora de escribir un código. Traigo el contenido aquí para no perderlo en el historial y tenerlo a mano.

    Yo me voy a tirar a la piscina y voy a decir que sí es posible escribir el código de un proyecto sin tests si lo pruebas a mano según lo estás desarrollando.

    Lo que no es posible hacer sin tests es mantenerlo. Porque cuando se hagan cambios en el software ya no va a ser el mismo software que el que has probado a mano cuando lo estabas desarrollando. Tendrías que probar a mano de nuevo todo el programa, y eso puede ser una pérdida de tiempo. ¿Cuándo entra un código en mantenimiento? En cuanto dejas de tener visible ese código después de escribirlo.

    Creo que la principal finalidad de los tests desde el punto de vista pragmático, más allá del «virtuosismo» de «soy guay, tengo tests, tengo buen coverage (JA)», es poder automatizar el poder comprobar que el software sigue funcionando bien conforme va pasando el tiempo de una forma automática y no intrusiva. Si hago un cambio de mantenimiento a un módulo de software quiero poder tener mi checklist ya implementada que me cubra todos los casos de uso de ese módulo de software para poder hacer la validación automáticamente y comprobar que no se introducen regresiones, o sea, que no he roto nada inesperado al hacer el cambio. (El software a veces se conecta de formas poco esperadas; cohesión siempre acaba habiendo y las interfaces de un módulo nunca son tan buenas como cabría esperar)

    [1] Para que este deeplink funcione hay que haberse unido antes al servidor.

  • Pasa septiembre, llega octubre, Apple actualiza las specs de algunos de sus modelos, pero el nuevo iPad «a secas» se sigue viendo igual que siempre, con su bezel, su pantalla rectangular, su Touch ID y su Apple Pencil de primera generación.

    Empiezo a pensar: ¿y si siguen sin actualizar el aspecto del iPad regular, aparte de para no canibalizar al iPad Air, porque busca ser el equivalente en tablets al iPhone SE? El iPhone SE también sigue teniendo pantalla rectangular y Touch ID, pese a tener el cuerpo de un iPhone 11 Pro.

    ¿Podría ser simplemente que ambas familias empezasen a converger en algún momento; iPad como un iPad SE, iPad Air como el iPad a secas, igual que el iPhone normal con bezel, iPad Pro como iPhone Pro?

  • Por eliminación.

    Elegí FreeBSD porque NVIDIA publica drivers para la ABI de FreeBSD. Lo que significa que puedo tener aceleración gráfica y tener mis pantallas con la resolución correcta en vez de usar el driver genérico xorg-vesa. No sirve de nada más porque NVENC no está disponible fuera de Windows y porque no uso FreeBSD para jugar.

    Eso es todo. No soy un fanboy de FreeBSD y si mis casos de uso hubiesen sido otros tal vez hubiese ganado otro sistema operativo. Pero ganó este. Los tres sistemas son muy similares entre sí de todos modos.


    Otros candidatos:

    • NetBSD: me gusta por su extremada simpleza, hecha para darle una perfecta portabilidad. El lema de NetBSD es “por supuesto que corre NetBSD”, haciendo referencia al hecho de que es posible instalarlo en muchísimas arquitecturas (incluso en Macs de principios de los años 90 o en Play Stations).
    • OpenBSD: lo admiro por su extrema seguridad, pero mis casos de uso con mi ordenador me llevan a admirarlo de lejos. OpenBSD es tan seguro que hace unos años eliminaron el soporte para Bluetooth porque es un protocolo inseguro y su driver no estaba bien mantenido.
  • Tengo una tabla como la siguiente:

    datetime               points
    2021-07-05 10:00:00    1
    2021-07-05 10:05:00    1
    2021-07-05 10:08:00    -1
    2021-07-05 10:10:00    1
    2021-07-05 10:11:00    -1

    Y quiero sacar las sumas acumulativas. Es decir, no quiero sacar simplemente un SUM(points) y que me devuelva 1, sino que quiero ir viendo, para cada fila, la suma parcial de todas las filas que hay hasta llegar a esa desde el principio.

    Por lo que veo en Stack Overflow, una forma universal de hacerlo aunque poco eficiente con tablas muy grandes, es utilizar INNER JOINs aplicados sobre la misma tabla que parcialmente vayan agrupando los resultados por fecha. Me hice algo como lo siguiente en mi caso usando un WITH para filtrar sólo aquellos resultados que realmente quiero sumar y así tratar de hacerlo más eficiente.

    WITH points AS (
      SELECT datetime, points
        FROM data
       WHERE target_id = 12345
    )
    SELECT a.datetime, a.points, SUM(b.points)
      FROM points a
           INNER JOIN points b
                   ON b.datetime <= a.datetime;
  • No entiendo por qué GitLab se ha convertido en la implementación de referencia para alojar repositorios con funciones extras como tareas, peticiones de integración o cuentas de usuario. Es lento, dificil de utilizar, dificil de instalar… y además, es un software que se sigue llamando «libre» porque tiene una versión comunitaria, pero que vista la capa de marketing que tiene como producto, no se siente tan libre.

    Y sin embargo es lo que plataformas como GNOME, Xfce o Free Desktop han instalado en los últimos años como alternativa a los clientes más duros pero simples como cgit. Una alternativa mucho más ligera que dispone de funciones web es Gitea. Una de las cosas buenas de las aplicaciones web hechas en Go es que igualmente se distribuyen como un binario que se puede arrancar de la forma que haga falta. Configurar un GitLab es absurdamente complicado.

  • No estoy siguiendo mucho el tema de GitHub Copilot más allá sobre los memes que ya se han hecho, así que tampoco puedo contar nada innovador.

    A los programadores nos encanta soltar siglas para todo. Una de ellas es DRY: do not repeat yourself. Resolver continuamente los mismos problemas y reescribir el mismo código es absurdo porque provoca código complicado de mantener. El código debería ser reusable.

    Excepto que no todo el código acaba siendo fácil de reutilizar. O, al menos, puede ser bastante excéntrico tratar de reutilizar cierto código. Crear librerías de funciones útiles que hagan las cosas sencillas pero que la librería estandar de nuestro lenguaje de programación no nos proporcione, o marcarse un Node.js y tener un ecosistema lleno de paquetes monofuncionales (en el sentido más literal de la palabra) para hacer cosas como comprobar si un array está vacío, si un número es par, o para introducir espacios en una palabra.

    «¿Un paquete para crear un array de N posiciones en JavaScript? Eso es absurdo». Posiblemente. El zero-dependency es un estilo de vida, y en el caso de lenguajes como JavaScript, reducir el número de dependencias en el package.json no le viene nada mal a la mayoría de paquetes. Pero probablemente para la mayoría de estas funciones, no puedas escribirlas de tirón sin tener que entrar en Google a buscar en Stack Overflow, y a veces no tenemos tiempo ni de buscar en Stack Overflow.

    Es aquí donde creo que las IAs de este estilo podrían tener potencial. No me hagas cambiar de ventana para buscar en internet cómo hacer X en Y, perder tiempo consultando la segunda respuesta porque la primera no aplica, luego la segunda pregunta porque la primera no contiene las respuesta que me interesa… En su lugar, deja que le diga al ordenador en palabras propias qué pretendo hacer y que me genere código sin levantar los dedos del teclado. O deja que automatice el código más aburrido y repetitivo de escribir para ahorrarme tiempo.

    Existen razones por las cuales ni quiero pedir acceso a la beta de GitHub Copilot, pero de usarlo, se me ocurrirían casos de uso interesantes que de otro modo tendría que resolver perdiendo tiempo para escribir la función o buscando en internet, como por ejemplo:

    • Dado este array asociativo de objetos ({item1: { k1: v1, k2: v2 }, item2: { k1: v3, k2: v4 }}), fabrica un índice inverso a partir del campo k2 de cada item del array asociativo.
    • Fabrica un array con integers monotónicamente crecientes ([0, 1, 2, 3, 4...]). La IA generaría algo como Array(40).fill(0).map((_, i) => i).
    • Haz una función que valide un e-mail (¿te sabes la regex de memoria sin buscar en internet? ¿te sabes los mil millones de casos edge que tiene el RFC de las direcciones de e-mail?).

    Parafraseándome a mí mismo en Twitter hace unos días,

    Si programas en Java llevas pudiendo hacer clic para que el ordenador te genere los getters y los setters de tus clases desde hace décadas. Esto podría revalorizar el análisis y el diseño y dejar al ordenador que rellene specs. Imagina escribir un TDD y que el IDE lo rellene.

    Trabajar en los procedimientos más complejos y reales y en la lógica de negocio que requiere intervención humana con el tiempo que gano cuando al pulsar un botón me rellena los métodos chorra tipo «buscar X en este array»? Lo compro. Y eso que no espero usar este producto.

    @makigas
  • El otro día enchufé mi ordenador portátil después de tenerlo dos días desconectado de la corriente pero encendido y en modo suspensión. La batería estaba al 95% de carga. Es curioso porque antes del downgrade, durante los meses en los que usé Big Sur, la batería se me descargaba más rápido en este tipo de casos. Hablamos de una pérdida del 30% o del 40% de la batería en ese mismo intervalo de tiempo.

    Me pregunto si habría algún tipo de cambio en App Nap o en algún componente del sistema operativo responsable de esto, que haga que consuma más batería en Big Sur. O si fue algún tipo de bug temporal que ha quedado resuelto en sucesivos parches del sistema operativo. (Sigo sin plantearme actualizar, de todos modos.)

  • No solo mintieron con lo de que Windows 10 iba a ser la última versión de Windows, sino que Windows 11 tiene por el momento una importante subida de requisitos mínimos que ha enfadado a bastante gente. Quizá tenga su explicación lógica: los requisitos mínimos de Windows 10 en 2015 fueron tan bajos que a cualquier máquina compatible con Windows 7 se le ofreció actualizar a la versión 10, y en algún momento habrá que empezar a dejar de lado máquinas de 11 o 12 años de vida. Sin embargo, tal vez el timing no sea el más adecuado para pedirle a gente que se deshaga de hardware perfectamente funcional solo porque no es de la generación de procesadores que a Microsoft le parece bien.

    Antes de que Microsoft decidiese tumbar la PC and Health Check bajo la promesa de mejorarla, la descargué y la instalé en mi gaming rig para ver la compatibilidad. Llevaba días escuchando que muchos ordenadores no tan viejos estaban reportando ser incompatibles, pero la herramienta hacía una pésima labor en decir por qué. El primer intento de ejecutarla sobre mi ordenador, comprado hace 7 meses, no me sorprendió del todo.

    Interesante.

    Hasta que Microsoft arregle su PC and Health Check y haga que muestre un mensaje de error un poco más claro, una forma de ver por qué no es compatible un ordenador con Windows 11 es utilizar WhyNotWin11. Este programa analiza las specs y muestra en detalle todas las specs mínimas para Windows 11 y las comprueba y reporta por separado de forma gráfica.

    Foto del GitHub, no es mi ordenador.

    Después de una pequeña confusión entre «Windows 11 requerirá activar Secure Boot» y «Windows 11 requerirá ser compatible con Secure Boot» (FreeBSD no utiliza todavía Secure Boot y no me gustaría complicarme el acceso a esa partición, bien gracias), el único problema está en TPM 2.0. Mi Ryzen tiene TPM, pero al ser un ordenador montado, se conoce que no viene activo por defecto en la configuración del UEFI.

    Para poder activar TPM tuve que consultar varios vídeos en YouTube que me explicasen cómo utilizar el menú UEFI de mi ordenador, entender por cuál de las docenas de submenús me tengo que meter, y ser capaz de localizar la entrada correcta del menú, que tiene el sensual nombre de AMD CPU fTPM (a veces parece que los nombres de las cosas se eligen dejando caminar un gato sobre el teclado…)

    Todo lo que podía pensar mientras hacía esto es cómo un usuario con menos conocimientos (y eso que yo no entiendo de hardware, por eso alguien montó mi ordenador por mí y por eso paralelamente mis otros dispositivos son Apple) iba a ser capaz de sobrevivir a este paso en el supuesto de que sea esto todo lo que tiene que hacer para hacer una máquina compatible con Windows 11.

    Después de hacer este paso, la PC and Health reportó que mi máquina ya podría recibir la actualización a Windows 11 (¡gracias!).

    Gracias, hombre.