How to access the value of an array key in a Javascript Map object?

I wrote this message in StackOverflow and just before clicking the Send button I stumbled upon the solution. I don’t want to lose it, and I don’t have time today to publish the solution, so I decided to do it in two parts. First, publish the question and later (tomorrow?) publish the solution. Here we go!

I can set() a value using an array as a key in a JS Map, but it seems that there isn’t a clean interface to access that same value using the symmetric get() method:

  let z = new Map {}
 
    z.set([1,2], "a"); // Works as expected: Map { [ 1, 2 ] => 'a' }
 
    z.get([1,2]); // undefined (!)

I suspect that this behaviour has something to do with the fact that in JS:

 [1,2] == [1,2] 
    false

I can use [1,2].toString() as a key and then the z.get([1,2].toString()) method works as expected, but I’m wondering if there is in any other «cleaner» way to code that.

UPDATE:
Well, Map objects are a new addition of ES6. And it seems that ES6 has a problem with Maps if you are trying to use them with object keys. This has been discussed here
https://esdiscuss.org/topic/maps-with-object-keys and here https://stackoverflow.com/questions/21838436/map-using-tuples-or-objects .

A solution that WorksForMe was proposed in that same StackOverflow thread, using an ad-hoc built HashMap class, that takes a hash function as parameter to properly store and use object keys (specifically, for my problem, array keys)

function HashMap(hash) {
  var map = new Map;
  var _set = map.set;
  var _get = map.get;
  var _has = map.has;
  var _delete = map.delete;
  map.set = function (k,v) {
    return _set.call(map, hash(k), v);
  }
  map.get = function (k) {
    return _get.call(map, hash(k));
  }
  map.has = function (k) {
    return _has.call(map, hash(k));
  }
  map.delete = function (k) {
    return _delete.call(map, hash(k));
  }
  return map;
}

I have used it as follows (note that JSON.stringify is NOT a hash function, but as I said, it works for my example because I certainly know that my array values are not going to have duplicates). I should think about a proper hash function or use something from here, but as I said, I’m lazy today 🙂

  let z = new HashMap(JSON.stringify);
  z.set([1,2], "a");
  z.get([1,2]); // "a"

VirtualBox headless en servidor Scaleway

Esta semana he necesitado instalar una máquina virtual de VirtualBox en un servidor Scaleway (de 2.9€/mes) sin entorno gráfico. La primera duda ha sido… ¿se puede? 🙂 Lo primero que necesitamos es instalar VirtualBox. La particularidad es que Scaleway no tiene un kernel vanilla sino que está bastante personalizado para adaptarlo a esta empresa de cloud hosting. Así que hay que descargar el código del kernel, ajustar su configuración a la misma que usa Scaleway, compilar los módulos necesarios y ahora sí, descargar e instalar VirtualBox. Gracias a $DEITY, alguien se ha pegado el curro de preparar un script al efecto. La última parte de ese script instalar una máquina virtual Windows en VirtualBox (yo no lo necesito, he comentado esas líneas).

Bien, ya tenemos el kernel preparado y VirtualBox instalado. Ahora, ¿cómo demonios instalo una máquina virtual a partir de una imagen .iso si no tengo entorno gráfico? Bueno, simulando el entorno gráfico a través de phpVirtualBox (sí, existe tal engendro y funciona de lujo). Además, este tutorial te explica cómo instalarlo paso a paso.

Finalmente, si quieres acceder a la consola que VirtualBox abre por defecto cuando lanzas una máquina virtual Linux, podrás hacerlo vía RDP (Remote Desktop Protocol). Tampoco sabía que una VBoxHeadless abría el puerto 9000 para acceso RDP. Desde tu host remoto puedes ver la consola de VirtualBox vía rdesktop (en Linux) o vía Microsoft Remote Desktop en OSX.

También es posible usar la línea de comandos para lanzar la máquina virtualbox desde una shell en Scaleway (sin necesidad de usar phpVirtualBox, pero es mucho menos intuitivo)

Euskalbar Chromerako

TL;DR;

Euskalbar Chromerako eskuragarri daukazu. Ctrl-Shift-U (klik bat, lehen bezala) sakatu eta zuzenean bilatu nahi duzun hitza idatzi. On egin! 🙂

Bertsio luzea

Euskalbar hasiera-hasieratik berridatzi izan behar da (Igor Leturiak egin du -Elhuyar- lan bikain hori, oso denbora laburrean). Zergatik? Firefox-en egindako plugin-ak modu batean programatzen ziren (XUL eta bere API propioa erabiliz) eta Chromen beste era batera (WebExtensions APIa erabiliz). Emaitza: plugin bat garatzerakoan lan bikoitza egin behar zenuen bi nabigatzaileetan erabili nahi izanez gero. Izan ere, MS Edge (lehen Internet Explorer zena) nabigatzaileak ere WebExtensions APIa erabiltzen du orain. Istorio luze bat laburbilduz: Euskalbarreko kodea zakarrontzira bota eta hutsetik, zerotik hasi behar izan da. Eta epe baten barruan: azaroak 1ean WebExtensions APIa erabiltzen ez duten pluginak desgaitu egin dira.

Gauzak horrela, Chrome asko erabiltzen dudanez nire lanerako, Euskalbar-aren kode berria moldatu egin dut Chromen ere erabili ahal izateko. Aldaketa txikiak izan dira. Gero Web Store-ra igo dut. Tartean, kode nagusian ekarpen gutxi batzuk egin ditut… Besteak beste, erabilgarritasunari begira, klik bakar batekin funtzionatu behar du Euskalbar: alegia, Ctrl+Shift+U edo MacOSX-n Cmd+Shit+U sakatuz, automatikoki testua bilatzeko eremua hautatu egin behar da… Firefoxen oraindik ez dugu lortu baina Chromen bai.

Ea horrela erabiltzaile batzuen antsietatea lasaitzen den 🙂

FAQ

Zergatik aldatu da Euskalbarraren egitura? Lehen toolbar bat genuen eskuragarri aldi oro…

Bai, WebExtensions APIak oraindik ez du hori egiten uzten. Utziko digu? Agian bai, agian ez… Baina APIak aukera hori ematen badu noizbait, ziur Euskalbarran sartzen dela

Chromerako eta Firefoxerako bertsioak berdinak dira?

Bai, oinarrian, iturburu-kode bera erabiltzen dute. Noski, berezitasun txiki batzuk ere aurkituko dituzu, baina xehetasunak izango dira, inoiz ez funtzionalitate berriak.

Instalar soporte yaml-dev en PHP para OSX

Receta rápida para instalar soporte YAML en PHP 5.6 para OSX Sierra.

Añadir tap de php a brew:

$ brew tap homebrew/homebrew-php

Instalar librería dinámica yaml.so

$ brew install php56-yaml

Comprobar ruta de instalación:

$ ls -l /usr/local/opt/php56-yaml
/usr/local/opt/php56-yaml -> ../Cellar/php56-yaml/1.3.0

Crear php.ini para poder editarlo e indicar que active la carga de yaml.so:

$ sudo cp /etc/php.ini.default /etc/php.ini

Activar extensión en php.ini:

$ sudo vi /etc/php.ini
extension=/usr/local/Cellar/php56-yaml/1.3.0/yaml.so

Comprobar que ha cargado (reiniciar Apache si el soporte YAML se quiere para el servidor web… en mi caso no hacía falta, dado que el soporte se requería para línea de comandos):

$ php -i "(command-line 'phpinfo()')" | grep -i yaml
LibYAML Support => enabled
LibYAML Version => 0.1.7

HackIt! 2017 Level 5. Desempolvando el viejo MacOS

Ojo, ¿qué ha pasado con el nivel 4? W0pr lo ha descrito a la perfección usando Radare. La verdad es que es una delicia leer sus posts. En lo que a DiarioLinux respecta, lo solucionamos usando IDA Pro (en casa del herrero cuchara de palo) Bueno, realmente lo solucionó Kotxerra mientras nosotros dormíamos plácidamente a las 4AM. Echadle la culpa a él, por ser tan eficiente 😉 De hecho, nos impartió un mini-taller sobre la solución. Lo tengo documentado en uno de los backups que hice, así que en cuanto tenga un rato, lo desempolvaré para dar otra posible solución.
Lo que me interesa ahora es mostrar cómo abordamos el nivel 5. Poca gente lo solucionó… si no recuerdo mal (y el pantallazo de este post así lo ratifica), sólo W0pr (hats-off again) Por lo que comenté con ellos, hicieron análisis estático del código desensamblado. Nosotros seguimos otra vía, seguramente más tortuosa (y obviamente con peores resultados) pero interesante como ejercicio. Pero vayamos por partes. ¿De qué trata el level 5, Infinite Loop? Nos pasan un archivo infiniteloop.sit que hay que crackear. Los ficheros .sit son archivos comprimidos (Stuffit) que guardaban el ejecutable de los viejos MacOS 9. Ojo al parche, porque lo primero que se nos ocurrió fue encontrar un descompresor para Linux, ejecutar un emulador de MacOS9 sobre el ejecutable y depurar. No íbamos mal encaminados… Salvo que los .sit guardan datos de recursos (conocidos como «resource forks«) y metadatos del ejecutable y, sin ellos, el ejecutable realmente no sirve para nada. Nótese la «gracia» del título del level (A fork in the road…)

Long story short, encontramos la forma de instalar un emulador de MacOS 9 (la versión 9.2, no valía ni la 9.0, ni la 9.1, por experiencia) sobre qemu… sobre MacOSX Sierra :), tras muchas vueltas, usando SheepShaver. Cuando digo muchas vueltas estoy hablando de unas 5-6 horas, con gente muy experimentada. Fallaba por todos los lados: la instalación, el sistema de archivos, cuelgues en medio de la instalación, and the kitchen sink.

Pero finalmente, conseguimos instalarlo, subir el .sit.hqx y ejecutar. ¡Magia!

Cuando lo comentamos con @marcan42 vimos brillo en sus ojos: «¡Por fin alguien que lo ha ejecutado!». Y no me extraña, la verdad. Sin embargo, las cosas no eran tan fáciles como nos esperábamos…

Lo primero que llama la atención es que, tras teaclear el código de unlock, asumíamos que podríamos cancelar y volver a intentarlo con otro código (básico para poder depurar). Pero no, la ventana de FAIL se quedaba fija en pantalla y NO había forma de quitarla, teniendo que resetear la máquina entera (OMFG!)
Lo siguiente que intentamos fue instalar un debugger en MacOS 9.2. Como puede observarse en la primera pantalla, donde se ve el logo de MacOS y debajo el texto «Debugger installed», tenemos instalado MacsBug, un debugger un tanto arcaico para Motorola 68000. La gracia es que para activar el debugger, es necesario pulsar la combinación de teclas «Command-Power» (Programmer’s key), lo cual, en qemu, y con un teclado de un MBP moderno, no logré hacerlo ¯\_(ツ)_/¯