Instalar Swift en Ubuntu

Aunque la página web oficial de Swift está hecha con las mejores intenciones y se actualiza de forma razonable, he visto que no era del todo precisa a la hora de explicar cómo instalar el compilador en Ubuntu, la distribución Linux que oficialmente soporta.
Como echo de menos programar y quería por fin darle una oportunidad a este lenguaje sin tener que instalar cosas en OSX, he tirado de máquina virtual y la instalación ha sido sencilla, pero la detallo a continuación por si tú también te animas.

Hay que comenzar descargando las herramientas de desarrollo.
Desde un terminal, instalamos algunas dependencias. En mi caso bastó con:
$ sudo apt-get install libncurses5
Aunque puede que necesites también otras como: clang, libicu-dev, libcurl4-openssl-dev, libpython2.7…
Ahora descomprimimos las herramientas y las movemos a una ubicación a nuestro gusto (yo prefiero /usr/local, pero vale cualquiera)
$ cd Descargas
$ tar zxf swift.....tar.gz
(El nombre del fichero descargado)
$ sudo mv swift..../ /usr/local/swift

Y por último, voy a crear una variable de entorno en mi terminal que añada al path la ruta a las herramientas de Swift, que ahora las tengo en /usr/local/swift/; así que edito un fichero que hay en mi carpeta personal:
$ nano .bashrc
Al final del fichero creo una variable llamada SWIFT_HOME y le asigno la cadena de texto con la ruta:
export SWIFT_HOME=/usr/local/swift
Y la añado al PATH de mi terminal mediante una concatenación:
export PATH=$SWIFT_HOME/usr/bin:$PATH

Esta misma fórmula se puede utilizar para otros casos, como por ejemplo para instalar el kit de desarrollo de Java, o añadir variables de entorno como rutas a otros programas que queramos invocar de forma sencilla.
Lo mejor de utilizar este sistema es que estas variables se cargan solo en terminales que ejecute con mi usuario, lo que me parece más limpio que añadirlas de forma global a todo el sistema o poner estos comandos al alcance de otros usuarios con los que compartas máquina.

En definitiva, una vez hecho todo esto, cierra el terminal y vuelve a abrirlo para que se carguen estas nuevas rutas. Podrás verificar que ya tienes a tu disposición las herramientas de Swift, por ejemplo pidiendo que te indique la versión:
$ swift --version
Puedes iniciar el intérprete simplemente invocando:
$ swift
Y salir del intérprete con:
> :quit

Adelgazar la web

Llevo un tiempo ya intentando aligerar este blog: he quitado todo tipo de plugins, menus innecesarios, adornos estéticos y un largo etcétera. Habrá (porque siempre debe haber de todo en la viña del señor) quien critique que siga utilizando el tema Twenty Eleven de WordPress en su versión más espartana posible cuando un blog actual que se precie estaría repleto de imágenes en alta resolución, fuentes tipográficas de alta calidad, cosas dinámicas, características sociales…
Y es que un simple paseo por el directorio de temas no deja lugar a la duda.
Y no me centro solamente en el blog.

Por eso me sorprendió no encontrarme solo en mi reticencia a recargar mi página personal más allá de lo estrictamente necesario. Fabien Sanglard lo deja bastante claro en este post. Su blog esta lleno de información sobre programación de gráficos y videojuegos, con especial atención a títulos antiguos. En él analiza la tecnología (habitualmente el código) detrás del avance de los juegos y lo recomendaría enormemente. No me preguntes cómo es que lo tengo en mi RSS desde hace años, porque no recuerdo cómo lo encontré, pero vale su peso en oro si te interesa este asunto mínimamente.

El caso es que su MacBook Air de mediados de 2011 (Intel i5 a 1,7 GHz de doble núcleo con HyperThreading; 4 GB de RAM DDR3 1333 Mhz; 128 GB de disco SSD) se pone como una moto al cargar cualquier página web moderna por culpa de videos que se auto-reproducen en los márgenes de las páginas, sonidos por doquier, procesos en paralelo (los famosos «helpers»), etc etc.
Una máquina de estas especificaciones debería poder renderizar una web con la punta de la nariz y sobrarle recursos para hacerlo rápido y sin sudar la gota gorda.
Y aun así, nanai. Decenas de peticiones HTTP y toneladas de memoria ocupada solo para mostrar algo sencillo.

Esta tendencia ha llegado incluso a Wired, donde un periodista no especialmente inspirado pone de relieve que una página web corriente y moliente ya ocupa lo mismo que el «Doom» original.
Los tiempos de carga se han vuelto absurdos, y aunque una web tenga fines comerciales y no pueda renunciar a una serie de características y a una estética cuidada, lo que sucede «por debajo» es demencial. Nick Heer lo analiza con números objetivos.
No son únicamente ya las tipografías, los videos que te asaltan sin que te lo esperes, o imágenes de cabecera que bien valdrían para imprimir un póster de tamaño monumental, sino que el formato AMP no ha ahorrado nada del ancho de banda que prometía ahorrar.

Y sí, hay en marcha una guerra abierta entre los bloqueadores de publicidad y los anti-bloqueadores de publicidad. Bloquearla parece la única vía posible para no perder todo el tiempo de tu vida siendo bombardeado por interminables series de anuncios. Pero la cosa no acaba ahí: intenta contabilizar todo el tiempo que pasas cerrando docenas de videos, miniaturas, capas de publicidad/marketing, mensajes de suscripción a newsletters, avisos sobre el uso de cookies (gracias UE! 😡)…

No quiero terminar sin acordarme de Nikita Prokopov que explica algo parecido en su blog, esta vez centrándose en como Android o Windows 10 devoran recursos para terminar haciendo poco más que, digamos, Windows 95. Vale, es una exageración, pero si lees su post entenderás a qué se refiere.
Y si no eres alguien muy «techie» o, sencillamente, no le prestas atención, pasarás por alto que en tu móvil la aplicación de Facebook ya ocupa medio giga, siendo simplemente una App que solo debe mostrar contenidos que están en verdad almacenados en un servidor. ¡¡¡Y no veas además el espacio que ocupa en lo que la app denomina «Caché»!!! Es demencial:

El problema de fondo es que cada vez disponemos de más recursos, pero eso no nos hace ser más eficientes, sino que los utilizamos sin pensar en lo que ello implica y sin preocuparnos por si hacemos un uso razonable o económico de ellos. Básicamente:
¿Sabes que construir carreteras más anchas no mejora los tiempos de viaje, ya que simplemente anima a toda la gente a conducir más?
De modo que, por favor, si vas a hacer algo en internet hazlo evitando malgastar recursos. Nuestras conexiones, nuestros planes de datos, nuestros ordenadores, la batería de tu smartphone cuando estás lejos de un cargador y nuestra paciencia (la de todos) te lo agradecerá.

Primeras horas usando MacOS Mojave

La pasada noche pude por fin hacer la instalación limpia de MacOS 10.14 (que ya iba siendo más que necesaria) y las sensaciones por ahora están siendo muy buenas. Todo funciona como uno espera de un sistema operativo veterano y construido sobre unos sólidos cimientos, pero por fin (desde Yosemite) estoy aprovechando las novedades que trae para el común de los mortales.

Las notas de voz por fin se sincronizan
No me explico como Apple pudo haber tardado tanto en meter sincronización por iCloud a iMessage. Y lo mismo sucedía con las Notas de voz. Esta novedad me viene de perlas porque las uso bastante, además de las tradicionales notas de texto; y poder pivotar entre dispositivos sin pasar por el peaje de iTunes es todo un acierto.
Como punto negativo, la iOSificación de macOS ya es más que evidente. «Notas de voz», «Bolsa» o «Casa» son simples ports de las versiones móviles y se echa en falta, por ejemplo, poder importar ficheros de audio como nota de voz.

El modo oscuro y los fondos dinámicos
Visualmente es lo más llamativo (por no decir lo único) de esta versión. Estará por ver si consigue tracción suficiente para que aplicaciones de terceros (tipo Office) o algunas páginas web (por ejemplo Facebook) se sumen al carro.
¡Por favor! ¡Más fondos dinámicos! Hay algo hipnótico en ellos conforme pasan las horas ante el monitor.

Pilas en el escritorio
La organización por pilas es eficaz y permite poner orden hasta en el más caótico escritorio. Es una idea útil, concreta y sencilla que se ha llevado a cabo de forma eficiente y bella. Probablemente «lo más OS X» que se ha implementado en macOS desde hace años.

Shell-scripts: errores, señales y trampas

Aunque hace bastante que no preparo ningún script al que valga la pena hacer mención, he estado repasando algunas ideas sobre el tratamiento de errores. El scripting se parece mucho a programar, pero como todo lenguaje, tiene sus puntos fuertes y sus carencias. En particular voy a centrarme en cómo determinar el comportamiento de un script cuando se produce un error durante su ejecución, y como ayudarnos de unas pocas directivas para detectarlos y depurarlos.
Todo lo que viene a continuación está hecho con Bash en mente, así que funcionará tanto en MacOS como en GNU/Linux porque es la Shell más extendida, pero no lo he probado con otros terminales. Por cierto, ya que voy a utilizar las palabras «foo» y «bar«, no está de más aclarar que no tienen ningún significado, simplemente están ahí porque hay que poner un nombre y por convencionalismo.

Detener el script en caso de error
Imaginemos un script con el siguiente código:

Su salida es lo que uno espera. Un error alertándonos de que no existe ningún comando con el nombre «foo» y luego se imprime la palabra «bar»:
./script.sh: line 3: foo: command not found
bar

Aunque ha habido un error, el script ha continuado ejecutándose en la siguiente instrucción. Esto puede resultarnos peligroso o inadecuado para lo que estemos preparando, así que podemos utilizar la directiva «-e» para evitarlo:

Ahora sí, el guión se detiene en cuanto surge el error:
./script.sh: line 4: foo: command not found

He de aclarar que aunque la concatenación de instrucciones tiene implicaciones similares, abusar de ellas convertiría nuestro código en un churro intelegible; pero por si acaso:
foo & echo «bar»: Detecta el error y ejecuta la siguiente instrucción
foo && echo «bar»: Detiene el script cuando el comando devuelve error

La directiva -e no sólo rige los errores de comandos no válidos, sino que se aplica de forma más amplia a otros ejemplos de código, por ejemplo, a resultados de una operación que hayamos almacenado en una variable:

Produce:
ls: foobar: No such file or directory

Si de forma puntual necesitásemos esquivar el comportamiento marcado por esta directiva, podremos utilizar un pequeño truco de lógica:

El operador OR (||) con el segundo operando siendo «true» permitirá continuar la ejecución:
./script.sh: line 4: foo: command not found
bar

Y si nuestro comando fuese una condición de un bucle o de un «if»? Se evaluaría como falso, como por ejemplo aquí:

Se tomaría la rama del «else» y veríamos:
ls: foobar: No such file or directory
bar

Por lo tanto, la directiva -e puede ser de gran ayuda para evitar que nuestro script cometa errores… y que los arrastre durante el resto de su ejecución, que según lo que haga, puede terminar en resultados desastrosos. Pero aún hay más.


Detener el script si el error está en una tubería
No, no vamos a hablar de fontanería digital:

Cuando el error forma parte de una tubería de comandos, donde la salida del primero es la entrada del segundo, y así sucesivamente hasta el final de la tubería; el terminal simplemente indica el error y ejecuta el último comando de la tubería.
¡Ojo! No ejecuta los comandos que estén después del que da error; únicamente el último:
./script.sh: line 4: foo: command not found
a
bar

El problema entonces es que tenemos una tubería rota. Y una fuga. Y no hay nada peor que una fuga en una tubería rota. Eso es horrible. No quieres que eso suceda.
Para evitar que el problema vaya a más, tenemos otra directiva adicional (-o pipefail). Y digo adicional porque requiere que «-e» también esté presente para surtir efecto.

Si, se ejecuta el último comando de la tubería, pero la ejecución se detiene antes de continuar:
./script.sh: line 4: foo: command not found
a

Detener el script si hay variables no declaradas
Supongamos esto:

Nos arroja una línea en blanco porque la variable $a no está inicializada y luego imprime «bar» en la siguiente línea. Hasta aquí todo correcto. Pero si queremos evitar el uso de variables sin inicializar, usaremos la directiva -u:

Y con esto detenemos el script al llegar a ese punto de la ejecución:
./script.sh: line 4: a: unbound variable

Hay un truco que da un valor por defecto a una variable si no está inicializada o si está vacía, dependiendo del operador que utilices. Si quieres consultar más detalles sobre estos operadores, hay mucha información disponible sobre Expansión de Parámetros.
La opción «-u» está implementada de forma suficientemente inteligente como para ser tolerante en estos casos. Por ejemplo:

Digamos que como la variable VAR no estaba incivilizada, el operador «:-» le asigna el valor de la variable «default». Por eso, la salida de estas líneas es:
5

Sin errores. Perfecto. Ahora veamos como aprovecharnos de esto para evaluar condiciones. El siguiente código se detiene porque la variable «mi_var» está sin inicializar y la directiva «-u» lo ha detectado:

Así lo muestra:
./script.sh: line 4: mi_var: unbound variable

Si queremos esquivarlo (y que el if pueda evaluar si mi_var está vacío o sin determinar, aprovecharemos ese operador:

Y obtenemos el mensaje:
mi_var no esta inicializada

No se detiene la ejecución por un error, ya que podemos evaluar la condición; pero conservamos la protección para no usar variables vacías más adelante. Lo puedes probar intentando mostrarla después por pantalla:

Te da:
mi_var no esta inicializada
./script.sh: line 10: mivar: unbound variable

Debug del código «por las bravas»
La opción «-x» permite imprimir por pantalla cada instrucción antes de que se ejecute. Si tienes un script con errores y todavía no los has localizado, tal vez te interese ir viendo paso a paso lo que sucede. Por ejemplo:

Tendrás:
+ a=5
+ echo 5
5
+ echo bar
bar

Simple, verdad?

Errores y trampas
De forma invisible, cada vez que hemos obtenido un error, el sistema recibe una señal ERR que podremos interceptar si queremos, mediante una trampa.
Una trampa no es más que un código que se ejecuta si se detecta la señal asociada. Algo así como una función de toda la vida, pero que en vez de ser disparada por una instrucción escrita por el programador, responde a la señal emitida por la máquina.

Bash (como otros lenguajes de programación) nos permite hacer esto de una forma bastante simple mediante la opción «-E» (en mayúscula). Por ejemplo:

Provoca:
./script.sh: line 5: foo: command not found
ERR detectado

En cuanto sale el error ERR, la trampa («trap») toma el control para ese tipo de señal y ejecuta la orden «echo ERR detectado». Podríamos hacer una solución un poco más rebuscada, que mostrase el número de línea:

Que arroja:
./script.sh: line 6: foo: command not found
ERR detectado en 6

O incluso, creando un procedimiento algo más estilizado:

Que puede resultar muy práctico si utilizamos el procedimiento para imprimir los errores de diferentes trampas, con el numero de linea también como ayuda:
./script.sh: line 10: foo: command not found
*** ERROR DETECTADO
*** Error en la linea 10

Por último, si modificamos el mensaje donde informamos de la línea del error y cambiamos la variable $1 (donde hemos recibido el número de línea) por el resultado de la función «caller»:

Podemos también mostrar el archivo en el que se produjo el error:
./script.sh: line 10: foo: command not found
*** ERROR DETECTADO
*** Error en la linea 10 ./script.sh

Lo cual puede ser muy útil si el script consiste de varios ficheros.

#################################
Recursos:
https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/
https://unix.stackexchange.com/questions/122845/using-a-b-for-variable-assignment-in-scripts/122878
https://unix.stackexchange.com/questions/39623/trap-err-and-echoing-the-error-line

Estás minando criptomonedas sin saberlo?


Empieza a ser preocupante con el auge de las criptodivisas (Bitcoin, Monero, etc.) que la avaricia de algunos webmasters esté pasando factura a los ordenadores de sus visitantes. Yo venía notando una carga de trabajo elevada en el portátil últimamente, cada vez que veía alguna serie online.

Es cierto que, por un lado, recurro a un sitio donde puedo verlas gratuitamente; pero lo rápido que se drenaba la batería en segundo plano y los (cada vez más) frecuentes avisos de Safari sobre una página que se había recargado por consumir muchos recursos llegaron a preocuparme. ¿Era un problema mío? ¿O había algún factor externo que provocaba estos síntomas?

Tampoco puedo negar que llevaba un tiempo navegando como si fuese Superman o algo así: ni antivirus, ni bloqueador de publicidad, ni nada de nada. A pelo. Como un superhéroe de The Defenders. Como un inconsciente. Fue poner un bloqueador en Safari (concretamente AdGuard) y mis sospechas se confirmaron de inmediato como podéis ver en la imagen que encabeza el post.

En definitiva, Internet es cada día un lugar más salvaje, donde cada bit y cada megahertzio que pueda ser explotado, será explotado. Y ahora ya no se trata de poner publicidad porno pagada a precio de perfumería cara. Ni de colarte programas con licencia shareware de 15 o 30 días. Ni de que te suscribas a otra newsletter. Ni de que te instales una app en tu móvil.
El Internet del lejano oeste en el que nos toca vivir estos días está plagado de redes sociales que ya han recolectado mucha información sobre ti antes incluso de que te registres. De servicios y aplicaciones que monitorizan en qué empleas tu tiempo, qué comes, qué ves en la tv, qué compras, qué sitios visitas. De auténticos delincuentes que te graban con tu propia webcam (y a veces ni eso) o que cifran tu disco duro para luego extorsionarte. Y de gente que te cuela un pequeño e ilegible trozo de Javascript para poner tu máquina a su servicio. Y dios sabe qué más.