Organizar los e-mails de GitHub

Pude poner orden hoy en la carpeta de archivo en la que normalmente vuelco todos los e-mails de notificaciones de GitHub una vez los he procesado, y que estaba empezando a acumular un tamaño no poco considerable. (Sobre por qué archivo todo en vez de eliminar algunos tipos de notificaciones, es otro asunto.)

En las notificaciones que tienen que ver con un repositorio (como un issue, un PR o una release), GitHub rellena la cabecera List-Id con el identificador del repositorio del que procede. List-Id es una cabecera estandar que la mayoría de clientes de correo usa para reconocer listas. En el caso de GitHub, la List-Id de un repositorio es <repo>.<user>.github.com.

De modo que con un poco de análisis, he podido organizar automáticamente por carpetas todas las notificaciones, para que las notificaciones de makigas/clank (cuya List-Id será clank.makigas.github.com) vayan a Archivo/github.com/makigas/clank, o las del repositorio danirod/rectball vayan a Archivo/github.com/danirod/rectball.

Un par de filtros automáticos se van a asegurar de que futuras notificaciones vayan directamente a esas carpetas, ya que normalmente las notificaciones llegan en momentos en los que no les puedo dedicar tiempo y luego es complicado escarbar mi bandeja de correo para localizar todos estos correos cuando sí tengo tiempo de ponerme con ello.

Pequeños detalles sobre los átomos en Erlang

La semana pasada empecé a publicar mi curso de Elixir en YouTube, y la recepción está siendo buena e incluso algo mejor de lo esperado. Intento ir lento para ponerlo fácil a quien nunca haya trabajado con este tipo de lenguajes, pero a la vez intento ir rápido para satisfacer a quien esté intentando seguirlo según lo subo (aunque casi sería mejor esperar un par de meses antes de verlo del tirón…)

Uno de los vídeos que subí ya habla sobre los átomos. Es un tipo de datos interesante para representar valores constantes que equivalen a su propio nombre. Al principio puede sonar raro. Al menos a mí me lo sonaba cuando vi por primera vez el concepto en Racket durante la universidad. En Racket, se les llama quotes, y se utiliza la tilde en vez de los dos puntos. Por ejemplo, 'banana, pero el principio es el mismo.

Una cosa que para no hacer un vídeo de nivel introductorio tan complejo no cuento, es que en la máquina virtual de Erlang, cada vez que se declara un átomo, se registra en una tabla de átomos (o Atom Table), que se comporta como un diccionario de átomos conocidos por la máquina virtual.

Si las operaciones que trabajan comparando átomos son rápidas (por ejemplo, x == :ok), lo es porque una vez que todos los átomos están indizados, a nivel interno la máquina virtual de Erlang no trata a un átomo como su valor, sino como su posición en la tabla, así que al final los átomos se gestionan también como números que representan posiciones, y sólo en el momento de comunicar un átomo al exterior es que vemos su representación alfanumérica.

Hablo siempre de alfanumérico porque un átomo contiene letras y caracteres del alfabeto, pero es importante distinguir que los identificadores en Elixir entienden de Unicode, y que por lo tanto, otros alfabetos diferentes también pueden ser codificados en átomos (:Βόρειος, mismamente).

Otra particularidad interesante es que el recolector de basura de Erlang nunca va a recolectar átomos que hayan caído en desuso. De modo que con el tiempo, la máquina virtual de Erlang va a tender a absorber todos aquellos átomos que hayan sido empleados. Dado que en Erlang ciertas construcciones como los propios nombres de los módulos o las listas de argumentos también se codifican con átomos, estas construcciones también van a tomar espacio.

Además, la tabla no es infinita. Los límites declarados por la máquina de Erlang avisan que, salvo que se modifique como parámetro al iniciar la máquina, como mucho se podrán declarar 1.048.576 átomos en la tabla. ¿Qué pasará cuando se alcance ese límite? Que la máquina fallará, como podemos probar rápidamente con este pequeño script:

for x <- 1..1048577, do: x |> Integer.to_string |> String.to_atom

Es una forma un poco fea y barata de generar 1.048.577 átomos a partir de cadenas de caracteres que generamos a su vez a partir de los números de un rango. Cuando ejecuto esto en mi máquina, la máquina de Erlang falla:

$ elixir foo.exs 
no more index entries in atom_tab (max=1048576)
Crash dump is being written to: erl_crash.dump…done

Homebrew Cask sin avisos de seguridad

Seguramente esto sea contrario a la política de seguridad de macOS, pero hoy no me ha quedado otra que instalar con Homebrew Cask una aplicación GUI que no está firmada y que por lo tanto no pasa la política de seguridad de macOS. Educadamente, macOS me invita a tirar el instalador a la papelera pero hace fallar a Cask, que no se espera esto.

Si hubiese descargado a mano el instalador, podría seguir las instrucciones habituales para abrir aplicaciones no firmadas: click derecho – Abrir, y olvidarme por hoy de este asunto. Pero, ¿click derecho en Homebrew? ¿Eh?

Bueno, mirando la página de ayuda del comando brew cask install, la opción que busco es --no-quarantine. Homebrew respeta las opciones de seguridad del sistema operativo y por defecto pone en cuarentena las descargas, igual que hacen los navegadores web, para que salte el sistema de seguridad de macOS al intentar usar el archivo y rechazarlo si no se puede identificar el origen de la aplicación.

% brew cask install foo --no-quarantine

Recomendaría usar con cautela esta opción, de todos modos, no sea que se instalen sorpresas en el ordenador por accidente.

Paso de parámetros al instalar gemas de Ruby

No se me ocurre otro lugar donde dejarlo, así que como no quiero volver a perder hora y media de mi vida reinstalando cosas la próxima vez que falle, lo voy a dejar aquí.

Cuando una gema de Ruby tenga extensiones nativas por debajo y se quiera parametrizar su compilación (por ejemplo, cambiar el CC o las CFLAGS), la manera correcta de hacer esto sería:

gem install ruby-debug-ide -- —-with-cflags=\”-Wno-implicit-function-declaration\”

Uso este ejemplo porque es este el culpable de haber estado una hora haciendo bundle install como un idiota sin entender por qué falla y falla y falla y falla.