Asm.js: Compilando a javascript

El contenido de este post no es mío. Es una traducción (libre) que me tome la libertad de hacer de lo que escribió  Jhon Resig en su blog acerca de Asm.js.El articulo me pareció muy interesante y enriquecedor y creí que seria muy bueno que este disponible en castellano, especialmente para aquellos que todavía no están convencidos del potencial de JavaScript. De más esta decir que recomiendo completamente que lean el articulo original en lugar de este si pueden leer ingles sin problemas.

El árticulo continene una muy buena explicación de como funciona asm.js, ademas de una estupenda entrevista a David Herman contandonos un poco los objetivos y lo que podemos esperar de asm.js en el futuro. Sin más, el articulo:

Link al árticulo original: http://ejohn.org/blog/asmjs-javascript-compile-target

Igual que muchos desarrolladores, estaba muy entusiasmado con lo que promete Asm.js. Enterarme que Asm.js esta disponible en Firefox Nightly hizo que mi interés aumente. Mucha gente también lo hizo, de hecho, cuando Mozilla y Epic anunciaron (mirror) que habían portado el motor Unreal 3 – y que funcionaba muy bien.

Hacer que el motor de un juego escrito en C++ corra en javascript, usando WebGL para sus gráficos, es un logro realmente increíble y se debe en parte al conjunto de herramientas desarrolladas por la gente de Mozilla.

Desde la salida del motor de Unreal 3 en javascript, comencé a seguir la recepción de esta noticia por twitter, blogs, etc y ademas de ver que muchos desarrolladores comenzaron a mostrar interés por las tecnologías abiertas que hicieron esto posible, también ví mucha confusión: ¿Asm.js es un plugin? ¿Mi código javascript sera más rápido si uso Asm.js? ¿Funciona en todos los browsers? Siento que Asm.js y las otras tecnologías relacionadas, son muy importantes y me gustaría explicar como funciona, así los desarrolladores saben que es lo que esta pasando y como se verán beneficiados.

¿Que es Asm.js?

Para entender Asm.js y donde se ubica dentro del browser, es necesario saber de donde viene y para que fue creado.

Asm.js viene de un nuevo tipo de aplicación js: aplicaciones C/C++ que fueron compiladas en JavaScript. Es un nuevo tipo de aplicaciones que surgieron a partir del proyecto de Mozilla Emscripten.

Emscripten toma código C/C++, lo pasa a través de LLVM y convierte el bytecode generado a JavaScript. (Asm.js es, concretamente, un subset de JavaScript).

Si el código Asm.js compilado hace algún tipo de renderizado, entonces seguramente sera manejado por WebGL (usando OpenGL para ello). De esta manera, todo el trabajo es llevado a cabo haciendo uso del browser y JavaScript pero esquivando, prácticamente, todo el camino normal de ejecución y renderizado que tienen las aplicaciones Javascript-en-el-browser normales..

Asm.js es un subset de JavaScript altamente limitado en cuanto a lo que puede hacer y sobre lo que puede operar. De esta forma, el código compilado a Asm.js puede ejecutarse rápidamente haciendo las menores suposiciones posibles, convirtiendo el código JavaScript directamente a ensamblador. Es importante tener en cuenta que Asm.js es simplemente JavaScript – Osea, no necesitamos ningún plugin especial para ejecutarlo en el browser (Aunque un browser capaz de detectar el código compilado en Asm.js puede hacerlo mucho más rápido). Es un subset especial de JavaScript optimizado para que sea más “performante”, especialmente cuando se trata de código compilado a JavaScript.

La mejor forma de entender como funciona, es mirar un poco el código compilado a Asm.js. Vamos a ver una función extraída de una aplicación real compilada a Asm.js (De la demostración BananaBread). Le dí un poco de formato a este código para que sea más fácil de digerir, pero normalmente es un montón de código JavaScript minificado.

Técnicamente, es código JavaScript, pero podemos ver que difiere bastante de lo que estamos acostumbrados a ver en aplicaciones normales que hacen uso del DOM.

Algunas cosas de las que podemos darnos cuentas simplemente mirando este código:

  • Este código en particular, solo trabaja con números. De hecho, todo el código compilado a Asm.js hace esto. Asm.js solo puede trabajar con un grupo selecto de tipos numéricos y ninguna otra estructura de datos (Esto incluye strings, booleanos y objetos).
  • Todo dato externo, es almacenado y referenciado desde un único objeto, denominado pila. Esencialmente, esta pila es un array gigante (Que intenta ser un array tipado,  altamente optimizado para mejorar su rendimiento). Todos los datos son almacenados dentro de este array reemplazando efectivamente a las variables globales, estructuras de datos, closures y cualquier otra forma de almacenamiento de datos.
  • Cuando se accede o se asigna algún dato, su valor es forzado a un tipo especifico, siempre. Por ejemplo f = e | 0; asigna a la variable f el valor de e pero también asegura que este valor va a ser un entero (| 0 justamente, convierte un valor a entero). También vemos esto con los números flotantes – fijate el uso de 0.0 y g[...] = +(...);.
  • Mirando los valores que entran y sale de las estructuras de datos, pareciera como si el dato estructurado representado por la variable c es un Int32Array (almacenando enteros de 32 bits. Los valores son siempre convertidos hacia o desde un entero usando| 0) y g es un Float32Array (almacenando flotantes de 32 bits. Los valores son siempre convertidos a un flotante encerrando el valor con +(...)).

Haciendo esto, el resultado esta altamente optimizado y puede ser convertido directamente desde esta sintaxis Asm.js hacia ensamblador sin tener que interpretarlo como tendría que hacerlo con JavaScript. Esto recorta muchas cosas que pueden hacer que un lenguaje dinámico, como Javascript, sea lento: Como la necesidad de un recolector de basura y tipos dinámicos.

Como ejemplo de un código Asm.js más “explicativo” vamos a ver uno sacado de la especificación de Asm.js:

function DiagModule(stdlib, foreign, heap) {
    "use asm";

    // Variable Declarations
    var sqrt = stdlib.Math.sqrt;

    // Function Declarations
    function square(x) {
        x = +x;
        return +(x*x);
    }

    function diag(x, y) {
        x = +x;
        y = +y;
        return +sqrt(square(x) + square(y));
    }

    return { diag: diag };
}

Este código es un poco más claro y podemos ver mejor como funciona Asm.js. Cada modulo está contenido dentro de una función y comienza con la directiva"use asm";. Esto le dice al interprete, que todo lo que se encuentra dentro de esta función debe ser tratado como Asm.js y ser compilado directamente a ensamblador.

Hay que prestar atención a los parámetros de la función: stdlib, foreign, and heap. El objeto stdLib tiene referencias a varias funciones matemáticas nativas. foreign proveé funcionalidades definidas por el usuario (Como podría ser, dibujar una figura en WebGL). Por último heap es un ArrayBuffer que puede ser visto, según el caso, como distintos tipos tales como Int32Array y Float32Array.

El resto se divide en tres partes: declaración de variables, declaración de funciones y por último, un objeto para exportar las funciones que serán expuestas al usuario.

La última parte, la que exporta las funciones, es muy importante, ya que permite que todo el código dentro del modulo pueda ser tratado como Asm.js y a la vez ser usado por código JavaScript normal.

De esta forma, podrías tener algo así usando el mencionado DiagModule:

document.body.onclick = function() {
    function DiagModule(stdlib){"use asm"; ... return { ... };}

    var diag = DiagModule({ Math: Math }).diag;
    alert(diag(10, 100));
};

Esto nos daría a DiagModule en Asm.js que sera tratado de manera especial por el interprete de JavaScript pero aún así estará disponible para otro código JavaScript (Esto quiere decir que podremos usarlo dentro de un evento onClick, por ejemplo)

¿Que tal es el rendimiento?

Actualmente, la única implementación que existe es en las versiones nightly de Firefox (y solo para un par de plataformas). Dicho esto, las primeras pruebas mostraron resultados muy, muy, buenos. En aplicaciones complejas (como los juegos mencionados) el rendimiento es solo 2 veces menor que el del código nativo compilado desde C++ (Lo que es comparable a otros lenguajes como Java o C#). Esto es enormemente más rápido que lo que logran los browsers actualmente, alrededor de 4 a 10 veces más que las ultimas versiones de Firefox y Chrome.

Esto es una enorme mejora sobre lo que tenemos actualmente. Considerando lo temprano de su desarrollo, podemos incluso pensar un rendimiento mucho mejor en las próximas releases de Asm.js

Es interesante ver la enorme diferencia entre Asm.js y los motores actuales en Firefox y Chrome. Una mejora de rendimiento de 4 a 10 veces es enorme (Es como comparar a los browsers actuales con el rendimiento de IE6).
Algo interesante, es que incluso con esta diferencia de rendimiento, muchos de los demos en Asm.js funcionan bien en las versiones actuales de Chrome y Firefox, lo que nos da un buen indicador del estado actual de los motores JavaScript. Sin embargo, su rendimiento no es tan bueno como el ofrecido por un browser capaz de optimizar código Asm.js.

Casos de uso

Hay que tener en cuenta que casi todas las aplicaciones que se usan con Asm.js actualmente son aplicaciones C/C++ compiladas usando Emscripten. Teniendo esto en cuenta, el tipo de aplicaciones que van a compilar a Asm.js, en el futuro cercano, son aquellas que se pueden beneficiar de la portabilidad de un browser, pero que son muy complejas como para ser hechas directamente en JavaScript.

Hasta ahora, la mayoría de los casos de uso se centraron en código donde el rendimiento es muy importante: Tales como juegos, manejo de gráficos, interpretes de lenguajes de programación y bibliotecas. Un vistazo rápido en la lista de proyectos de Emscripten muestra muchos proyectos que serán de uso instantáneo para muchos desarrolladores.

Soporte para Asm.js

Como vimos al principio la versión nightly de Firefox es el único browser que soporta la optimización de Asm.js.

Sin embargo, es importante destacar que el código formateado para Asm.js es ni más ni menos que código Javascript, con un importante set de restricciones. Por esta razón, el código compilado a Asm.js puede correr en otros browsers al igual que cualquier otro código JavaScript, incluso si el browser no lo soporta.

La parte crítica del rompecabezas es el rendimiento de ese código: Si el browser no soporta arrays tipados o no compila especialmente el código Asm.js el rendimiento sera mucho menor.

Asm.js y el desarrollo web

Como seguramente te habrás dado cuenta, el código Asm.js no esta pensado para que lo escribamos a mano. Sera necesario alguna herramienta para escribirlo y van a ser necesarios algunos cambios en como escribiríamos código JavaScript normal para poder usarlo. El caso de uso más común para Asm.js en este momento es con aplicaciones compiladas desde C/C++ a JavaScript. Casi ninguna de estas aplicaciones interactuan con el DOM de forma significativa, mas allá de usar WebGL y demas.

Para que esto pueda ser usado por desarrolladores normales es necesario tener lenguajes más “accesibles” que puedan compilar a Asm.js. El mejor candidato, hasta el momento, es LLJS que esta comenzando a lograr compilar hacia Asm.js. Es importante notar que un lenguaje como LLJS va a seguir siendo un poco diferente de lo que seria un código “normal” escrito en Javascript y seguramente confundira a muchos usuarios de JavaScript. Incluso con un lenguaje más “amigable” cómo LLJS seguramente seguirá siendo usando únicamente por desarrolladores avanzados que necesitan optimizar al máximo su código.

Incluso con LLJS, o cualquier otro lenguaje, que pueda permitir escribir código Asm.js “a mano” no habría un DOM igualmente optimizado sobre el cual trabajar. El entorno ideal seria uno donde podamos compilar LLJS y el DOM juntos para crear un único “bloque” en  Asm.js para que corran de forma simultanea. No estoy seguro cual seria el rendimiento de algo así, pero ¡Me encantaría verlo!

Preguntas y respuestas con David Herman

Le mandé algunas preguntas a David Herman (Investigador senior en Mozilla Research) para intentar obtener un poco más de claridad en como funcionan juntas todas estas piezas de Asm.js y como deberíamos esperar beneficiarnos de ellas. Amablemente se tomo el tiempo de responderme en profundidad y darme respuestas excelentes. Espero que las encuentren tan iluminadoras como yo.

¿Cual es el objetivo de Asm.js? ¿A que publico apunta?

Nuestro objetivo es hacer que la web abierta sea una máquina virtual completa, sobre la cual compilar otros lenguajes y plataformas. En esta primer realease, estamos enfocados en compilar código de bajo nivel como C y C++. Más adelante esperamos darle soporte a constructores de más alto nivel como objectos estructurados y recolectores de basura. De esta forma nos gustaría soportar aplicaciones de otras plataformas como la máquina virtual de Java o .NET.

Ya que asm.js esta pensado, en realidad, para expandir las bases de la web, hay un rango muy amplio de público potencial. Pensamos que un grupo que pueden sacar gran provecho de esto son los desarrolladores de juegos que necesitan acceder a todo el poder computacional que puedan. Pero los desarrolladores web son ingeniosos y siempre encuentran formas de usar todas las herramientas que tienen disponible en formas que no habíamos planeado, así que lo que más deseo es que asm.js sea una tecnología que permita todo tipo de aplicaciones innovadoras que no puedo imaginar actualmente.

¿Tiene sentido crear una versión más “amigable” de Asm.js, como una versión actualizada de LLJS? ¿Se planea expandir el proyecto a ser algo más que algo sobre lo cual compilar?

Totalmente. De hecho, mi colega James Long anuncio recientemente que hizo un fork de LLJS que compila a asm.js. Mi equipo en Mozilla Research quiere incorporar el trabajo de James y hacer que LLJS ofrezca soporte oficial para asm.js.

En mi oponion, normalmente vas a querer escribir asm.js a mano en un par de casos muy limitados, como en cualquier lenguaje ensamblador. Normalmente, vas a querer usar lenguajes más expresivos que compilen eficientemente a él. Por supuesto, cuando los lenguajes, como JavaScript, se vuelven muy expresivos, perdes predictivilidad sobre el rendimiento. (Mi amigo Slava Egorov escribio un post muy bueno explicando los retos de escribir código de alto rendimiento en lenguajes de alto nivel) LLJS esta pensado para un puesto intermedio, como un ensamble de C a asm.js que es más facil de escribir que código asm.js crúdo pero que es más predecible en cuanto a optimización que el código JS normal. Pero a diferencia de C, tiene una buena interoperatibilidad con el JS común. De forma que puedas escribir la mayor parte de tu aplicación en código de forma más flexible en JS y concentrarte en escribir solamente las partes más criticas en LLJS.


Hay un nuevo debate entre los browsers que soportan Asm.js y los que no, similar al que ocurrió durante la última carrera sobre rendimiento de JavaScript en 2008/2009. A pesar de que técnicamente el código Asm.js pueda ejecutarse en cualquier lugar, la diferencia de rendimiento va a ser demasiado grande en muchos casos. Dada esta división, ¿por que elijieron compilar a JavaScript? ¿Por que JavaScript en vez de un lenguaje especial o un plugin?

Para empezar, no creo que la división sea tan horrible como vos la menciones: Creamos demos sorprendentes que funcionan muy bien en navegadores actuales pero que se benefician enormemente usando la optimización ofrecida por asm.js

Es cierto que podes crear aplicaciones que van a depender completamente de la fuerte optimizacion de asm.js para que sean usbales. Al mismo tiempo, como cualquier feature nueva de la plataforma web, las aplicaciones pueden decidir tener un comportamiento distinto con algún fallback menos “costoso”. Hay una gran diferencia en aquellas aplicaciones que funcionan con un rendimiento diferente que aquellas que directamente no funcionan.

Tene en cuenta que la carrera por el rendimiento en los browsers que comenzo a finales de la decada del 2000 fue muy buena para la web y las aplicaciones evolucionaron mucho junto con los browsers. Creo que va a ocurrir lo mismo con asm.js.


¿Cómo compararias Asm.js con el Cliente Nativo de Google? Parece tener objetivos similares a pesar de que Asm.js tiene la ventaja de “simplemente funcionar” en cualquier lugar que pueda correr JavaSCript. ¿Han hecho comparaciones en cuanto a rendimiento?

Bueno, el Cliente Nativo es un poco diferente, ya que implica distribuir código ensamlador especifico de cada plataforma; No creo que Google haya pensado en eso como una tecnologia para contenido web (Si no más bien para contenido disponible en el Web Store de Chrome o extensiones de Chrome), o al menos no en el último tiempo.

El Cliente Nativo Portable (PNaCl, Portable Native Client) tiene un objetivo más similar, usando bitcode LLVM independiente de la plataforma en vez de ensamblador puro. Como dijiste, la primer ventaja de asm.js es la compatibilidad con los browsers existentes. Incluso evitamos tener que crear una sistema de interfaz y repetir el trabajo ya realizado para  las web API como lo hace la Pepper API, ya que asm.js tiene acceso a la API existente usando JavaScript directamente. Por último, tenemos la ventaja de que es muy facil de  implementar: Luke Wagner tuvo nuestra primera implementacion de OdinMonkey en Firefox en tan solo un par de meses, trabajando mayormente solo. Dado que asm.js no tiene un gran numero de llamadas al sistema y API y porque esta hecho usando la sintaxis de JavaScript, podes reusar un monton de lo que ya existe para los motores JavaScript y el runtime de la web.

Podemos hacer comparaciones de rendimiento con PNaCl pero llevaria algo de trabajo y estamos más enfocados en achicar la brecha que existe con el rendimiento nativo. Esperamos poder configurar ciertos benchmarks automaticos así podemos mostrar nuestro progreso comparado con los compiladores nativos de C/C++.


Emscripten, otro proyecto de Mozilla, parece ser el principal productor de código compatible con Asm.js. ¿Cuanto de Asm.js es conducido por las necesidades del proyecto Emscripten? ¿Que beneficios obtuvo Emscripten ahora que las mejoras fueron hechas al nivel del motor?

Usamos Emscripten como nuestro primer test case para asm.js como una forma de asegurarnos que tiene lo necesario para ser usado por aplicaciones nativas reales. Y por supuesto que que los beneficios de Emscripten benefician a cualquiera que tenga aplicaciones nativas y quieran portarlas tal como Epic Games, con quienes nos unimos para portar el engine Unreal 3 a la web en tan solo un par de días usando Emscripten y asm.js.

Pero asm.js puede beneficiar a cualquiera que quiera compilar a un conjunto de bajo-nivel de JavaScript. Por ejemplo, hemos hablado con los muchachos que construyeron el compilador Mandreel, que funciona similar a como lo hace Emscripten. Creemos que se pueden beneficiar al compilar a am.js como empezo haciendolo Emscripten.

Alon Zakai Estubo recompilando benchmarks que generalmente corren 2 veces más lentos que los nativos, donde antes veiamos resultados de 5 a 10 o 20 veces. Esto tan solo en nuestra primer release de OdinMonkey, el backend para asm.js del motor JavaScript SpiderMonkey de Mozilla. Espero ver más mejoras en los próximos meses.


¿Que tan fluida es la especificación de Asm.js? ¿Estan dispuestos a agregar features adicionales (como ser, estructuas de dato más avanzadas) a medida que más autores de compiladores apunten a el?

Podes estar seguro. Luke Wagner escribio un roadmap para asm.js y OdinMonkey en la wiki de Mozilla, en donde se discute algunos de los próximos planes. Tengo que decirte que ninguna es fija todavía, pero te puede dar una idea sobre lo que vamos a trabajar más adelante. Estoy muy emocionado por agregar soporte para los objetos estructurados de ES6. Esto podria proveer recoleción de basura ademas de estructuras de datos tipadas que podrian ayudar a compiladores como JSIL que compilan a lenguajes como C# o Java a JavaScript. Tambien esperamos usar algunos de los tipos de valores propuestos para ES7 para proveer soporte para numeros flotantes de 32 bits, enteros de 64 bits e incluso vectores de longitud fija para soportar SIMD.

¿Sera posible, o práctico, tener un transcompilador JavaScript-a-Asm.js?

Seguramente, sí, pero ¿práctico? No estoy seguro. ¿Te acordas en Inception, cada vez que metes un sueño-dentro-de-un-sueño, el tiempo se hacia más lento? Seguramente pasará lo mismo cada vez que quieras intentar correr un motor de JS dentro de sí mismo. Haciendo un calculo rapido, si asm.js ejecuta código nativo a la mitad del tiempo normal, entonces ejecutar un motor de JS en asm.js va a ejecutar código a la mitad de la velocidad normal de ese motor.

Claro que, vas a poder intentar ejecutar un motor de JS en otro distinto y ¿Quien sabe? el rendimiento en realidad nunca es algo tan claro como lo es en la teoria. ¡Agradeceria que algunos hackers intrepidos lo prueben! De hecho, Alex Tatiyants, estudiante de Stanford, ya compilo el motor SpiderMonkey de Mozilla a JS usando Emscripten; Todo lo que tenes que hacer es usar los flags para el compilador de Emscripten para generar asm.js. Alguien con más tiempo disponible deberia intentarlo.


Actualmente, todo el código del DOM o especifico del browser se maneja por fuera de Asm.js. ¿Hay intenciones de hacer una versión del DOM Emscripten-a-Asm.js-compilado (Algo así como DOM.js)?

Esta es una idea estupenda. Quizá sea un poco complicado con la versión preliminar de asm.js que no tiene soporte para objetos. ¡A medida que hagamos crecer asm.js para incluir soporte para los objetos tipados de ES6 algo como esto puede ser feasible y bastante eficiente!

Una buena aplicación de esto puede ser ver que tanto de la plataforma web puede ser autocontenida con un buen rendimiento. Una de las motivaciones detras de DOM.js fue ver si una implementación del DOM escrita puramente en JS puede resolver el problema tracional del manejo de referencias y de memoria entre la pila de JS y el conteo de referencias de los objetos DOM de C++. Con el soporte a asm.js, DOM.js puede obtener estas mejoras de rendimientos más los beneficios de estructuras de dato más optimizadas. Es algo que vale la pena investigar.


Dado que es bastante dificil de escribir Asm.js, en comparación con código JavaScript normal, ¿que tipo de herramientas les gustaria tener para poder ayudar a desarrolladores o autores de compiladores?

Lo primero y principal, necesitamos lenguajes como LLJS, como ya mencionaste, que compilen a asm.js. Y tendremos algunos de los retos comunes de compilar a la web, como mapear el código generado de nuevo al código original en las herramientas para desarrolladores del browser, usando tecnologias como source maps. Me encantaria ver que se mejoren los source maps para incorporar más información de debugging, aunque seguramente habrá una relación costo/beneficio a la que ajustarse entre la información minima que se obtiene de los source maps y la información super compleja de los formatos de metadatos tales como DWARF.

Para asm.js, me parece que me voy a concentrar en LLJS por ahora, pero siempre agradesco ideas de los desarrolladores sobre como mejorar su experiencia.


Supongo que estan abiertos a trabajar con otros fabricantes de browsers ¿Que discución o colaboración a habido hasta ahora?

Por supuesto. Hemos tenido un par de discuciones informales y se han mostrado predispuestos, seguramente tendremos más. Soy muy optimista en que podamos trabajar con varios fabricantes de browsers para tener asm.js en cualquier lugar que podamos implementarlo verdaderamente sin mucho esfuerzo o cambios de arquitectura. Como dije, el hecho de que Luke haya podido implementar OdinMonkey en cuestion de unos pocos meses es muy alentador. Estaria feliz de ver un bug para soportar asm.js en V8.

Pero más interesa que los desarrolladores puedan hechar un vistazo a asm.js y ver que opinan y nos provean su feedback, tanto a nosotros como a otros fabricantes.

Desarrollo web móvil – Inspeccionando webs en dispositivos moviles

Creo que no hace falta aclarar que desde hace, relativamente, poco tiempo los dispositivos móviles (smartphones, tablets) se volvieron una de las principales fuentes de tráfico a sitios web.
Trabajar con los mismos suele ser engorroso, debido a que no contamos con las facilidades que tenemos en los entornos de escritorio.
Sin embargo, en la mayoría de los browsers modernos, es posible utilizar el inspector web de forma remota para poder debuggear nuestra aplicación en tiempo real.
A continuación, voy a recopilar los métodos para activar esta funcionalidad en los browsers más conocidos e iré actualizando el post en caso de encontrar otro browser.

Safari – iOS 6+

Para poder utilizar el inspector web remoto de Safari, necesitamos la última versión de este browser para escritorio, la cual no esta disponible para ninguna otra plataforma ademas de OSX (que novedad ¿no?)

Activar el inspector en iOS

Debemos dirigirnos a Settings -> Safari -> Advance y habilitar la opción Web Inspector

Activar la inspección remota en Safari

Abrimos las settings de Safari (cmd + ,) vamos a la pestaña Advance y marcamos Show develop menu in menu bar.

Ahora vamos a ver un nuevo menú en la barra superior llamado Develop.  Abrimos el sitio que queremos inspeccionar en el dispositivo iOS con Safari, hacemos click en ese menú y vamos a ver una opción con el nombre del mismo. Dentro veremos una lista de los sitios inspeccionables que tenemos abiertos. Clickeamos en él y tendremos el inspector abierto, pudiendo hacer (casi) todo lo que hacemos con el inspector web de Safari en el escritorio.

Firefox – Android

Para hacer esto, necesitamos Firefox 15+ (Tanto en nuestro escritorio como en Android)

Activar el inspector en Android

Abrimos Firefox , vamos a about:config y cambiamos las siguientes settings:

devtools.debugger.force-local -> false

devtools.debugger.remote-enabled -> true

Reiniciamos el browser (normalmente basta con apretar Home en nuestro dispositivo, pero puede que necesitemos Matar la aplicación usando algún task manager.

Activar el debugging remoto

Abrimos Firefox, en el dispositivo Android, vamos nuevamente a about:config, y cambiamos:

devtools.debugger.remote-enabled -> true.

Reiniciamos el browser y ahora podemos activar el debugger remoto desde el menu  Web developer.

Tenemos que indicar la ip de nuestro teléfono y el puerto (por defecto, 6000.  Se puede cambiar mediante la opción devtools.debugger.remote-port en about:config, desde el dispositivo.)

Chrome – Android

Para esto, necesitamos descargar el SDK de Android.

Habilitar el debugging web

Abrimos Chrome en nuestro dispositivo Android, vamos a Settings -> Developer Tools y marcamos Enable USB web debugging.

Forwardear las conexiones al puerto del debugger

Conectamos mediante USB nuestro dispositivo y nos aseguramos de tener activada la opción USB debugging dentro de las Developer options.

En nuestro escritorio, dentro de la carpeta que contiene al SDK de Android, vamos a ver otra llamada platform-tools y dentro un programa abd.

Ejecutamos: adb forward tcp:9222 localabstract:chrome_devtools_remote

Inspeccionar

Abrimos Chrome en nuestro escritorio y vamos a http://localhost:9222 ahí veremos una lista de las pestañas abiertas en el dispositivo.  Al hacer click en una de ellas se abrirá la ventana del inspector y podremos comenzar a trabajar.

Opera Mobile

Activar DragonFly en el escritorio

Abrimos Opera y vamos a Tools -> Advance -> Opera dragonFly en el menú superior.   Luego buscamos el icono de Remote debugging configuration en el panel de DragonFly, seleccionamos el puerto y hacemos click en apply.

Conectar el dispositivo

Abrimos Opera Mobile e introducimos opera:debug en la barra de direcciones. Luego debemos ingresar la ip del escritorio donde tenemos corriendo Dragonfly y el puerto. Una vez hecho veremos la confirmación de que la conexión se realizo de forma exitosa.

Hecho esto, podemos abrir cualquier url y seleccionarla mediante el icono de debugging context en Dragonfly.

Fuentes:

Curiosidades de javascript: Valores primitivos, null y undefined

Es normal escuchar a muchos desarrolladores decir que en javascript todo es un objeto. Esto en realidad es un malentendido, puesto que existen los llamados valores primitivos, strings, números y booleanos, además de dos valores especiales null y undefined

Veamos los valores primitivos. En principio, uno pensaría que son objetos, ya que podemos sin ningún problema acceder a algunos métodos de los mismos.

A primera vista, la variable foo (y por tanto, el string “bar”) es un objeto. Sin embargo, esto no es cierto. Lo que ocurre es que javascript envuelve los valores primitivos con objetos cada vez que queremos acceder a algún método y/o propiedad de los mismos. Dicho objeto, es destruido luego de la operación.

Intentar asignar 5 a la propiedad num de foo no arroja ningún tipo de error, puesto que al intentar acceder a dicha propiedad foo es envuelto en un objeto, pero luego este es destruido, por lo tanto, foo.num toma el valor undefined.

El tipo de objeto usado para envolver los valores primitivos, depende del tipo de valor. Así, los strings son envueltos por objetos String(), los numéricos por Number() y booleanos por Boolean().

Por último, no hay que confundir un valor primitivo string con un objeto del tipo String (creado mediante new String()), a pesar que puedan comportarse de forma similar (lo mismo ocurre para otros tipos de valores)

Veamos ahora que ocurre con los otros dos tipos de valores que no son objetos, undefined y null.

Cuando declaramos una variable (y no le asignamos ningún valor) esta posee el valor undefined. También es el valor que devuelve una función que no devuelve ningún valor explícito.

De acuerdo al standard Ecmascript 5, undefined es un valor primitivo de tipo undefined. Es decir, así como {false, true} son los posibles valores del tipo booleano, undefined es el único valor posible del tipo undefined.

Algo similar ocurre con null, ya que es el único valor posible para el tipo de datos null. Se utiliza para representar la ausencia intencionada de un valor. Es decir. Una variable va a valer null únicamente si es asignado de forma explícita.

Es importante tener en cuenta que ocurre al momento de comparar null o undefined con otros valores, ya sea porque utilizamos el operador == (en lugar de ===) o bien porque intentamos operar con valores de distinto tipo (Ej: 3 + null).

Cuando es evaluado como booleano, ambos devuelven false.

Al momento de intentar evaluarlos como número, undefined es evaluado como NaN

null, en cambio, es evaluado como 0+.

Por último, al intentar evaluarlos como string, cada uno equivale al string “undefined” o “null” respectivamente.

Hay que destacar que undefined es, también, una propiedad del objeto global (window, en los browsers) cuyo valor es undefined. De acuerdo al estandard Ecma, undefined es una variable que no puede ser escrita.
Sin embargo, en browsers antiguos (Ej: Firefox anterior a la versión 4) esto no era así y podíamos asignar cualquier valor a dicha propiedad, por lo que debemos tener esto en cuenta si pretendemos soportar dichos browsers.

Como última mención, podemos ver que si aplicamos el operador typeof, ocurre lo siguiente:

Es importante notar que null es tomado como de tipo object a pesar que si intentamos acceder a una propiedad de una variable null o undefined recibiremos un error de tipos.

Bitacora #2: Tile.js generator

Dejando los posts sobre cosas curiosas de javascript para más adelante, cuento un poco sobre una pequeña utilidad que arme para usar en el port del gorillas.

Se trata de un simple generador de tiles para usar sobre un contexto 2d.
Dado que el juego original no utilizaba imágenes, me pareció que no seria correcto hacer un clon que sí las use, por lo que pensé en dibujar los elementos del juego (gorilas, edificios, bananas y el sol) con primitivas del contexto 2d.

Como seria bastante engorroso imaginarme donde tendría que poner cada punto, se me ocurrió hacer una ‘pizarra’ en la que se dibuje cada punto que selecciono. Estos se van guardando en memoria para luego obtener una función con el código para dibujar dichos puntos.

Para manejar de forma ‘elegante’ la orientación a objetos en javascript, use la libreria Base.js. Esta provee de una serie de objetos y métodos que hacen que la herencia y la creación de ‘clases’ sea más llevadero.
El resto del código, consiste en una clase con un ‘canvas virtual’ que lleva registro de los puntos que fueron dibujados para luego obtener el código de cada uno (tanto la clase ‘canvas’ como la clase ‘dot’ saben como obtener su código).
Ademas, al momento de obtener las funciones, se puede especificar un ‘multiplicador’ para reducir el tamaño de los puntos, de esta forma se puede dibujar en grande y de forma comoda, para luego disminuir el tamaño.

Ejemplo:

Tile Generator

Dibujamos esto...

 

 

Drawed gorilla

y obtenemos la función para dibujar esto...

El script es bastante sencillo y carece de buenas prácticas, pero es útil para lo que necesito en este momento.

Para verlo en acción: http://tehsis.me/tilegen/
Repo en github: https://github.com/tehsis/Tile.js-Generator

En el futuro espero hacerlo extensible a primitivas distinta a los puntos (rectángulos en realidad) y poder dibujar otras cosas. No seria complicado, pero ahora la prioridad es el gorillas :D.

Dejo un par de links interesantes,

Base.js – Mini librería para trabajar con objetos, clases, herencia, etc de forma ‘clasica’
Load.js – Mini librería para ‘importar’ scripts js mediante código.
10 Things I learned from jQuery source – Video de Paul Irish contando 10 técnicas interesantes que estan presentes en el código de jQuery.
Tutorial del elemento Canvas (MDC) – Lindo y llevadero tutorial del MDC sobre la etiqueta canvas y el contexto 2d.

Bitacora #1: Funciones y scope en javascript

Para comenzar con la bitácora, me pareció innecesario hablar sobre que es javascript, como se ejecuta y cosas básicas sobre su sintaxis.
Es que de hecho, la mayoría de los desarrolladores web, sabemos que posee una sintaxis basada en C, que es un dialecto de la especificación ECMAScript y que se usa para hacer efectos raros en las páginas web… Si ya se, es prácticamente un cliché decir que javascript es mucho más poderoso que eso, teniendo ejemplos como Twitter, Facebook, Gmail y un largo etcétera, creo que ya no hace falta aclararlo.
Lo cierto es que durante mucho tiempo la mayoría simplemente buscaba en Google como hacer algo en particular sobre Javascript, cambiaba un par de cositas para adaptarlo a su necesidad y decia ‘Tengo que aprender javascript algún día’. Ese ‘algún día’ llego hace rato y hoy es difícil pensar un sitio o un sistema web que no lo utilice.
Es quizás por esto que mucha gente no entiende exactamente como se utiliza Javascript y por lo que muchas de sus capacidades como lenguaje, en el sentido estricto de la palabra, están subestimadas.
Por ello, elegí comenzar a escribir sobre los conceptos básicos que en mi opinión, hacen especial a javascript

Funciones y scopes

Las funciones en javascript son incluso más importantes que en otros lenguajes dado que son el único delimitador de contexto que tenemos a diferencia de C++ o Java en donde las variables tienen alcance solamente en el bloque en donde fueron definidas.

En el ejemplo, definimos una variable a en el contexto global, dentro de una función creamos una variable del mismo nombre a la cual le asignamos un valor. Ejecutamos la función y comprobamos que la variable a, tal y como es de esperarse, no fue modificada.
Sin embargo, dentro del bloque if, creamos una nueva variable a, le asignamos un valor y fuera del bloque, la variable continua teniendo ese valor. Como dije anteriormente, el único scope en javascript son las funciones y el scope global.

Funciones anónimas

Otra cosa interesante de javascript, es la posibilidad de crear funciones anónimas. Con ellas, podemos hacer dos cosas (en principio); asignarlas a una variable e invocarlas como una función común:

O bien, decirles que se autoejecuten, de la siguiente manera:

Esto último, es muy útil, no solo nos permite simular bloques para solucionar el problema del scope que mencionamos antes, si no que sirve para solucionar un problema bastante común e incluso visto en algunos frameworks famosos y es que, cualquier variable que definamos fuera de una función, se encuentra en el scope global. De modo que es muy común que diferentes scripts sobrescriban variables por estar definiendo todas en el contexto global.
Una solución a esto, es la de encerrar todo nuestro código en una gran función anónima que se autoejecute y solo exponer aquellas variables estrictamente necesarias y de esta forma simular espacios de nombres en nuestros scripts.
Un ejemplo práctico de esto, lo podemos ver en el código fuente del framework jQuery

Como vemos, al incluir jQuery en nuestro sitio web, se ejecuta una gran función anónima dentro de la cual, se crea una variable con toda la funcionalidad del framework y luego se la asigna a una propiedad del objeto window.
Para no entrar en mucho detalle simplemente tenemos que saber que dentro de un browser, el objeto window define nuestro contexto global. Es decir, jQuery en el contexto global es el mismo objeto que window.jQuery.

De esta forma, la única colisión de nombres posible es que haya otro objeto llamado jQuery (o $) dentro de window.

Nota 1: El $ en window.$ no es ni más ni menos que un identificador para una variable cualquiera. Es exactamente lo mismo usar jQuery o $, no posee ningún poder otro poder mágico.

Nota 2: Es recomendable usar jQuery en lugar de $, ya que este último es utilizado por otros frameworks y podemos tener efectos no muy deseados si tratamos de trabajar con ellos.

Conclusión

Las funciones en javascript son el único delimitador de scope que tenemos, esto podría resultar un grave problema ya que cualquier identificador que definamos fuera de una función puede colisionar con otro definido en otro script. Es por esto que es una buena práctica encerrar todo nuestro script en funciones anónimas que se autoejecuten y exponer (asignándolos como propiedades del objeto window) solamente aquellos identificadores imprescindibles.
Para cerrar, podemos decir que en javascsript las funciones son objetos, pero eso mejor lo vemos mañana.

Antes de cerrar, quiero comentar que pueden encontrar el estado actual del juego que comente en el post anterior en https://github.com/tehsis/Gorillas.js
Por lo pronto, estuve trabajando más que nada en crear un marco de trabajo para solucionar algunos problemas que vamos a ver más adelante.

[Perl] Expresiones regulares y cuantificadores no codiciosos

Hace poco tiempo tuve problemas con una regex que no tomaba lo que, al parecer, yo le indicaba. El problema no es grave, pero tiene que ver sobre como Perl trata las expresiones regulares y las wildcards.

Por ejemplo, si tenes el siguiente string “See spot, see spot run, run spot run” y tratamos de capturar lo que se encuentra antes del primer ‘spot’ podríamos querer hacer algo como esto:

Lo cual nos mostraría en pantalla ‘See spot, See spot run, run ‘. En vez del primer ‘See ‘ que ya cumpliría con lo que dice nuestra regex. El tema está en que Perl, tratara de matchear lo más que pueda ya que hace uso de cuantificadores codiciosos (greedy quantifiers). De modo que para traer el primer ‘See ‘ debemos hacer uso de los ‘cuantificadores no codiciosos’ (non-greedy quantifiers), En este caso ‘*?’  que tratara de matchear 0 o más lo menos que pueda. Es decir, cambiando a:

Obtendremos el primer ‘See ‘.

Del mismo modo, asì como con el cuantificador codicioso ‘+’ matchearemos 1 o 0 veces, con ‘+?’ matchearemos 0 o 1 veces (primero 0, luego una). y usando el cuantificador no codicioso  {x,y}? podremos matchear x veces, pero no màs de y.

Conclusión, un problema bastante sencillo pero que puede generar algunas confusiones.

Fuente:  http://perldoc.perl.org/perlretut.html

Importando datos SQL con Perl

Hace algun tiempo tenia que importar CSV a una tabla que tenia guardada en una base de datos Postgre para una materia de la escuela.

Como tenia un problema con la forma oficial para hacer esto y no funcionaba internet, con la ayuda de Perl arme un pequeño script que, leyendo desde un archivo CSV, generaba sentencias “insert” con los datos para luego pegarlos en una consola y de esa forma tener mís datos importados… como quien dice, una “rebuscada freak”

En fin, el código pueden verlo a continuación o bien desde mí cuenta de gitHub en: https://github.com/tehsis/importSQL

EDIT: Debido a que el script fue sufriendo algunos cambios desde que lo publique, dejo solo el link al repo

Presentando a El Goblin

Desde hace un par de semanas, comence a aprender Perl y para esto inicie un pequeño proyecto sobre un buscador de páginas web, sin más intenciones que obtener sitios y buscarlos mediante tags y principalmente, aprender a trabajar con Perl y otras herramientas.
Así fue que nacio “The Goblin Search Engine”. Una serie de scripts que permitian añadir sitios a una base de datos  (MongoDB) y luego buscarlos mediante los tags  (los cuales son obtenidos del sitio).

Habiendo avanzado ya un poco, me dispuse a darle un objetivo más “práctico” a este buscador para que no muera solamente en un puñado de código mal armado y es así como nace Goblin como proyecto personal.

¿En que consiste?

Actualmente, esta dividido en dos partes. “The Goblin server” y “The Goblin client”, conectados el uno con el otro mediante SOAP.
El primero, como ya dije, esta hecho completamente en Perl y es el encargado de agregar los sitios a la base de datos, realizar las busquedas y brindarle los resultados al cliente.
El segundo (el cliente) no es más que una API para poder acceder a los servicios del servidor (valga la redundancia).
Tambien junto con el cliente se incluye un script como ejemplo para usarlo.

¿Y el objetivo?

El objetivo sigue siendo aprender. Las ideas que tengo para implementar en Goblin son muchas y seguramente apareceran más sobre la marcha.
De momento, es solamente un pseudo buscador de páginas web indexadas en una BD que no esta pensado bajo ningun punto de vista para usarlo en producción (aunque bien podría servir como base).
Sin dudas, el siguiente paso sera hacerlo más robusto, actualmente es bastante inestable y “facil de romper”  ademas, claro, que carece de muchas caracteristicas que podrian considerarse un “must” en este tipo de apps. Vamos, que hay que mejorarle TODO.

En conclusión. La idea de este post era solamente comentar sobre Goblin. No recomiendo su uso actualmente, pero el código esta ahí listo para que lo bajen y hagan lo que quieran con el (bueno, siempre que la GPLv3 lo permita ;) )

Por último, quiero agradecer a @guitarrear por impulsarme a aprender Perl y por consiguiente, a comenzar ese humilde proyecto :)

http://github.com/tehsis/Goblin

Simphple Gallery 0.1 – Galeria de imagenes simple con PHP

Bueno… bastante hace ya de mí último post… espero poder dedicarle más tiempo a esto en estos días, aunque no prometo nada.

Hace unos días para una web que estoy armando, necesitaba hacer una galería de imágenes de forma que el usuario pueda agregar y sacar imágenes a su antojo y como buscando por la web me encontré con varías galerías que usaban AJAX o Flash, decidí armar una donde predomine la simpleza.

El script esta hecho enteramente en PHP de forma que no dependa del navegador que estemos usando para poder visualizarlo correctamente.

Para usarlo, solamente deben crear un directorio llamado “img/” en el mismo lugar que donde tienen el archivo gallery.php (aunque pueden cambiarlo modificando dicho archivo) y meter allí las imágenes que quieren que formen parte de la galería. Luego incluyen el script mediante:

 
<?php include("gallery.php"); ?>

Dentro de su página o bien crean un link directo al mismo.

Al comienzo del código fuente, van a poder encontrar las variables que pueden modificar para poder “personalizar” el script, tal como el directorio desde el cual se tomaran las imágenes, el ancho y largo con el que seran mostradas y los textos que hacen de link a las imágenes anterior y siguiente (de forma que sea sencillo traducirlo).

Las imágenes son redimensionadas por medio de HTML. Sé que podría usar gd para que no pierdan tanta calidad, pero 1-Nunca use gd 2-Por el momento preferí que los requisitos para usar el script sean los menos posibles.

El script no genera ningún estilo CSS ni nada que se le parezca. Esto fue adrede para que podemos agregar uno de nuestra propia manufactura simplemente envolviendo nuestro include con las correspondientes etiquetas. Por ejemplo:

 
<div id='gallery'>

<?php include("gallery.php"); ?>

</div>

Tengan en cuenta que de momento, no hay ningún filtro para los archivos dentro del directorio que contiene las imágenes así que asegurense de meter allí solamente archivos de imágenes (.jpg,.png,etc) si no quieren resultados raros.

Posiblemente más adelante agregue esto junto con el redimensionamiento de imágenes via gd… ya veremos que sale. Por el momento, solamente quería compartir esto que arme para mí uso personal esperando que a alguien más le pueda servir.

Sin más, el link de descarga:

Descargar:  Simphple Gallery 0.1

Qt 4.5 publicado

Por medio de El Código K y Barrapunto, leo que ya se encuentra disponible la versión 4.5 de las bibliotecas Qt.
Esta actualización incluye muchas novedades, entre las que se destacan: un nuevo SDK (que incluye todas las herramientas necesarias para desarrollar con Qt), la posibilidad de licenciar nuestras creaciones con LGPL (lo que suma una nueva opción a el embrollo ya existente), mejoras en la versión de 64bits para Cocoa (mac), mejoras en la integración con Webkit (ahora podremos hacer uso del plugin de flash para Netscape en nuestras aplicaciones) y las siempre discutibles mejoras de performance.

Junto con esto, publican tambien (junto al SDK) la versión 1.0.0 de Qt Creator. Un entorno de desarrollo multiplataforma que nos permite trabajar de forma “amigable” con estas bibliotecas.

Opinión personal, es interesante ver el desarrollo que le esta dando Nokia a todo lo que se refiera a Qt, una historia que vengo siguiendo de cerca por ser Qt una de mis APIs favoritas para aplicaciones gráficas.
El hecho de que ahora también sea distribuida con licencia LGPL, nos permitirá crear aplicaciones cerradas y/o comerciales de forma completamente gratuita, algo que a la FSF no le gusta mucho pero que me parece interesante que se haya hecho, eliminando así toda posible “disputa” respecto a las licencias de Qt. Recordemos que la opción comercial sigue existiendo para aquellos que lo requieran.
Aprovecho para decir que en estos días (seguramente la semana que viene, después de mis exámenes) publicare por fin la segunda parte de mi articulo sobre Qt Jambi… Esta vez es en serio ;)