27 agosto, 2008

json-tinyurl

Simon Willison anuncia la disponibilidad de un nuevo servicio para acortar URLs (tinyurl.com) pero utilizable desde Javascript.

JSON (y JSON-P) envoltura sobre la API de TinyURL.

Otros servicios de Simon Willison del mismo estilo: json-time y json-head.

25 agosto, 2008

TraceMonkey

Desde hace unos meses, la presión que se está aplicando al mundo de los lenguajes interpretados no deja de aumentar. Con un crecimiento importante de todos ellos (y en especial, Ruby, Python o Javascript) y con un número de programadores que llegan desde lenguajes compilados (C++) o semi-compilados (Java), se intenta que mejore el rendimiento de los lenguajes y que se amplien sus características para que los recién llegados se encuentren a gusto. Aplicar las tecnologías de compilación a los lenguajes interpretados no sólo es posible sino que además están apareciendo una serie de artículos en el sector que muestran que las ventajas históricas que se creía exclusivas de los lenguajes compilados también pueden aplicarse a los interpretados. En esa línea, Brendan Eich, uno de los artífices de Javascript, anuncia que para la próxima versión de Firefox (3.1) se intentará tener terminado lo que ellos llaman TraceMonkey: una serie de optimizaciones en el intérprete que consiguen mejoras de hasta un 2200% en determinados casos. Las optimizaciones aprovecharán, entre otras, las siguientes técnicas:

  • desplegado de funciones en línea (repetir el código de la función a llamar en el punto de llamada de forma que se evitan saltos y la función se ejecuta como si fuese parte del código).
  • inferencia de tipos para optimizar el funcionamiento de los operadores (p.ej. cuando se sabe que las variables a sumar con + son cadenas, realizar una concatenación directa sin intentar deducir los tipos).
  • optimización general de los bucles reduciendo las instrucciones ejecutadas a cada paso.
En el artículo de Eich se explica con detalle cómo han sido posibles dichas mejoras. Hace poco, y en la misma línea, John Resig anunciaba la disponibilidad en Firefox 3.1 de la función querySelectorAll que permitirá acelerar todas las librerías (jQuery, Prototype, Dojo, Mootools, YahooUI, ...) que implementan por su cuenta dicha funcionalidad de selección de nodos de un documento xHTML. Parece que empieza a haber una cierta unanimidad en cuanto a la dirección a seguir por parte de la comunidad de desarrolladores. Y, sin duda, eso es algo a celebrar.

22 agosto, 2008

Google Gears 0.4

La versión 0.4 de Google Gears acaba de ser publicada. Entre otras mejoras destacan:

  • Nueva API de geolocalización para conocer desde Javascript la ubicación del equipo o dispositivo actual con getCurrentPosition() o un evento para detectar cambios de posición con watchPosition().
  • API de Blobs para guardar datos en formato binario como imágenes o archivos.
  • La API de escritorio se ha actualizado para permitir seleccionar varios archivos locales.
  • Nuevos eventos onprogress() para reportar el progreso de las descargas y envíos (upload) de archivos.
  • Traducción a 40 lenguajes.
  • Más cambios.
Estoy actualmente desarrollando una aplicación con Gears Mobile y la dirección que está tomando esta librería empieza a impresionar hasta el punto de que no sería de extrañar que empezasen a hacer uso de ella toda clase de aplicaciones web del tipo de YouTube, Flickr, FaceBook, etc. y alcanzar la ubicuidad de Flash.
Addendum: Dion Almaer propone otras posibles extensiones de Gears, como Notificación para enviar mensajes a la bandeja de iconos del escritorio, Crypto para trabajos de encriptación, Logging para facilitar notificaciones internas, Desktop Shortcut para crear accesos directos desde el escritorio, o Image Manipulation para permitir trabajar con imágenes desde el navegador. Introducción a la serie de artículos.

19 agosto, 2008

Tutorial de Mootools 1.2

En ConsiderOpen.com empezaron ayer un tutorial de 30 días para aprender MooTools y JavaScript aunque presuponen un conocimiento básico previo de HTML y de CSS.

0.5 segundos

Durante un experimento en Google originado por una petición expresa de los usuarios, se aumentó el número de resultados ofrecidos por el buscador Google de 10 a 30. Inmediatamente, el tráfico recibido y el beneficio obtenido por los anuncios patrocinados cayó un 20%.

Una página con 10 resultados llevaba 0.4 segundos para generarse, pero una con 30 llevaba 0.9. Aunque parezca de chiste incrementos tan pequeños como 0.1 segundos, según otro experimento de Amazon, son percibidos por los usuarios de forma negativa. La velocidad de respuesta es, por tanto, crítica para el éxito de una página o aplicación web.

18 agosto, 2008

REST, simplemente no lo entiendo

Hace unos días, y al estilo del cuento el Nuevo Traje del Emperador, Damien Katz resaltaba que aunque REST está muy bien, hay dos verbos que apenas se usan (PUT y DELETE) y que debe ser suficiente con POST (para modificaciones) y GET (para obtener información que además puede ser cacheada de forma natural). Comprendiendo dónde falla SOAP, REST no lo convierte en una respuesta adecuada. Si lo simple es mejor (KISS) ¿para qué complicarse con los verbos PUT y DELETE que no están extendidos y que complican el estándar? La respuesta de la comunidad no se hizo esperar. Todos trataban de convencerle de las ventajas, pero las evidencias están ahí. El argumento más utilizado era que los verbos forman parte de la especificación HTTP sobre la que la web ha crecido, pero ciertamente, de los cuatro verbos sólo GET y POST han tenido una acogida para su uso por los servidores de aplicación y respecto a las ventajas por el cache de información, sólo se está aplicando realmente al verbo GET, por lo que la contestación de Damien tiene todo el sentido: "La web está construida sobre REST, por tanto REST es bueno" Caca de vaca. Lo cierto es que la propuesta de uso de Damien sigue respetando la filosofía REST, aunque no de forma tan purista y sí de forma más simple. Recordemos que REST no está respaldado por la industria sino que es, más bien, una propuesta de la misma comunidad de desarrolladores, más de "garaje". La industria sigue respaldando SOAP, aunque cada vez menos, por ser buzzword compliant, es decir, que cumple con las palabras técnicas de moda como XML. Da igual que se haya demostrado que es un estándar tan complejo que resulta extremadamente incómodo e inadecuado programar sobre él. Dare Obasanjo responde a Damien en este excelente post. Explica en qué consiste exactamente crear servicios web basados en REST y hace énfasis en el punto más complejo, el de no utilizar cookies para guardar el estado entre peticiones y usar enlaces hipertexto en su lugar. Finalmente indica que realmente no es necesario usar los verbos en discordia (PUT y DELETE), a pesar de que es lo que más se ha difundido de la filosofía REST y que, por tanto, lo que proponía originalmente Damien no implica alejarse de las ventajas de la propuesta original. Como único caso, el verbo PUT (equivalente a un UPDATE) es idempotente, lo que quiere decir que independientemente del número de veces que se realice, el resultado es el mismo, lo que no puede suponerse para el POST.

Actualización

He actualizado este artículo porque Dave Winer, el que creó XML-RPC (otra de las opciones y de la que partió SOAP como origen) indica que siempre olvidamos XML-RPC. Como autor de dos de los sistemas RPC está obviamente en contra de REST. Además, dice que echa en falta un formato para serializar estructuras, listas y tipos escalares. Como bien le contesta Simon Willison, ese sería JSON, al que por cierto tampoco le gusta nada a Winer.

Actualización

Finalmente, en otro post, Damien reconoce haberse equivocado al no leer la especificación de REST y en particular el capítulo 5, tal y como le indica Sam Ruby. Básicamente el extendido uso de POST y GET para servicios web también se puede considerar RESTful.

11 agosto, 2008

Parseador simple para HTML/DOM en PHP

SimpleHTMLDom. Documentación. Descargar.

Se trata de un parseador implementado en PHP5+ que facilita enormemente manipular código HTML. Soporta HTML inválido y es capaz de encontrar etiquetas en una página HTML con selectores del estilo de jQuery.

Ejemplos:

  • Obtener elementos de HTML
    // Leer el DOM a partir de la URL
    $html = file_get_html('http://www.google.com/');
    
    // Encuentra todas las imágenes
    foreach($html->find('img') as $element)
           echo $element->src . '
    ';
    
    // Encuentra todos los enlaces
    foreach($html->find('a') as $element)
           echo $element->href . '
    ';
    
  • Modificar elementos HTML
    // Crea una estructura DOM a partir de una cadena
    $html = str_get_html('
    Hola
    Mundo
    '); $html->find('div', 1)->class = 'barra'; $html->find('div[id=hola]', 0)->innertext = 'tonta'; echo $html; // Lo que genera:
    tonta
    mundo
  • Extrae contenido desde HTML
    // Vuelca el contenido (sin etiquetas) de HTML, o sea, convertir a texto
    echo file_get_html('http://www.google.com/')->plaintext;
    
  • Filtrado del código HTML de SlashDot.org
    // Leer el DOM a partir de la URL
    $html = file_get_html('http://slashdot.org/');
    
    // Encontrar todos los bloques de artículos
    foreach($html->find('div.article') as $article) {
        $item['title']     = $article->find('div.title', 0)->plaintext; // extrae el título
        $item['intro']    = $article->find('div.intro', 0)->plaintext;  // extrae la intro
        $item['details'] = $article->find('div.details', 0)->plaintext; // extrae los detalles
        $articles[] = $item;
    }
    
    print_r($articles);
    

Rápida adopción de Flash respecto al navegador

Flash puede lograr la ubicuidad en la web entera con nuevas capacidades en apenas 18 meses mientras que la Open Web se enfrenta a una ventana de tiempo de 5 años en el mejor de los casos para difundir nuevas capacidades. Reducir ese diferencia desde 42 meses hasta 0 es el desafío de la Open Web.
Interesante cita de Alex Russell (Dojo Toolkit). Entre otras cosas da que pensar en la posibilidad de aprovechar desde Javascript las posibilidades de Flash o incluso de aprovechar que Flash incluye una versión de Javascript (ActionScript) que es verdaderamente multiplataforma. Sin embargo, no hay que olvidar que no es Javascript el problema de la compatibilidad entre navegadores, sino el DOM y las diferencias que cada fabricante se ha empeñado en introducir.

Hay otros datos sobre la implantación de Flash que se ven en un comentario de esa página:
  • La adopción del Adobe Flash Player es más rápida de lo indicado. El Player 9 (con compilación Just-In-Time, etc...) llego al 97% de los usuarios en 12 meses. Su Update 3 (con vídeo H.264) alcanzó el 82% en seis meses.
  • Ninguna versión hizo uso del mecanismo de autoactualización reservado para seguridad. Es el contenido el que ha movido esos niveles de adopción.
  • Tener más del 80% del soporte de los usuarios, sin tener en cuenta marcas de navegador y en apenas seis meses resulta una gran ventaja.
  • Un factor que he sospechado que ha influido para la lenta adopción de un navegador es que implica un riesgo de cambio en las rutinas visuales/táctiles diarias de los usuarios. Los navegadores tienen una distribución de elementos, un menú, y preferencias que hay que investigar. Adobe Flash Player es simplemente invisible. No hay hábitos que cambiar, no hay riesgo de romper la concentración diaria. Las novedades visibles pueden enlentecer la adopción.
  • [...]
  • Abrazando tecnologías multi-navegador, en lugar de refugiarse en un nicho propio de cada marca, audiencias más amplias podrán usar nuevas habilidades más rápidamente.

07 agosto, 2008

Servicios Web con window.name

Hace unos días se proponía el uso de window.name para guardar información que se mantiene en una pestaña o ventana del navegador aunque se reutilice para cargar una nueva página. El navegador impide el acceso en el caso de un iframe a menos que éste mostrando una página del mismo dominio que el padre.

La gente de Dojo ha ideado un sistema de consulta de servicios web que, basado en window.name, permite saltarse de forma controlada la restricción del navegador de impedir el acceso a marcos que carguen páginas de otros dominios distintos al actual.

Eso mismo se podía hacer ya con JSONP: realizar una consulta a un servicio web de forma que la respuesta tuviese la forma callback( {"respuesta_en_json":"ok"} ) donde callback es el nombre de la función javascript a la que se le pasa la respuesta en formato JSON y que se indica al realizar la consulta.

En este caso, se utiliza un iframe para hacer la consulta al servicio y su respuesta sería similar a la siguiente:


<html><script type="text/javascript">
window.name = document.getElementsByTagName("script")[0].innerHTML.match(/temp\s*=([\w\W]*)/)[1];history.go(-1);
temp= {
    id:"4",
    lastName:"Z",
    created: new Date(1218058428000),
    nbsp; firstName:"MIKI"
}
</script></html>

Es decir, la respuesta se indica en la variable temp, que se convierte en cadena y se guarda en window.name. Inmediatamente después, se vuelve atrás en el marco (el equivalente a indicar el comando volver en el navegador) para que el dominio de la página vuelva a ser el mismo que el de la página padre y pueda así accederse a window.name.

El código de la página principal sería el siguiente:


<html>
<body>
<iframe frameborder="0" id="ifr" onload="loaded()" src="/window.name/blank.html" style="border: 1px dotted red;"></iframe>

<br /><button onclick="go()">Run...</button><br />

<div id="results" style="border: 1px dotted red;"></div>

<script type="text/javascript">
var started= false;
function loaded() {
 if (!started) return;
 started= false;
 document.getElementById('results').innerHTML= getWin().name;
}
function getWin() {
 ifr=document.getElementById('ifr');
 if (~navigator.userAgent.indexOf('MSIE')) {
  win= ifr.window;
 } else {
  win= ifr.contentWindow;
 }
 return win;
}
function go() {
 started= true;
 win= getWin();
 win.location="http://localhost/dos.html";
}
</script>
</body></html>

Al principio, el iframe contiene una página en blanco del mismo dominio que la principal (http://127.0.0.1). Cuando se pulsa el botón Run, se ejecuta la función go, que carga en el iframe el servicio solicitado (del dominio http://localhost) y al terminar de cargar se dispara el evento onload y por tanto la función loaded que ya tiene acceso a la propiedad window.name del iframe.

Éste último paso podría dar un error en caso de que la página cargada en el iframe siguiese en el dominio http://localhost, pero como al finalizar la carga vuelve atrás al dominio http://127.0.0.1, el acceso se permite.

La función getWin se utiliza para acceder a la propiedad window del iframe, ya que se hace de forma distinta en Firefox y en el IExplorer (para variar).

06 agosto, 2008

Drizzle, un MySQL reducido


Drizzle
es un proyecto que tiene como objetivo crear una base de datos optimizada para concurrencia masiva y para arquitecturas modernas con múltiples CPUs o multinúcleo. En definitiva, pensada para servir de motor a las aplicaciones web a partir de un micro-núcleo extensible con módulos conforme se vayan necesitando.

Partiendo del omnipresente MySQL, irán eliminando todas aquellas características que no se utilicen o no resulten de utilidad hasta dejar sólo lo básico y que resulte fiable, rápida, escalable y simple de gestionar e instalar.

Los procedimientos almacenados, las vistas, los triggers, la caché de consultas, los statements preparados, el sistema de permisos o las inserciones con conversión de datos se han quitado, y con ellos toda lógica de negocio. Los tipos de campo se han simplificado y, probablemente se añadirán nuevos como IPv4, IPv6 o UUID (16 bytes). Se va a eliminar mucho código y motores de datos. Y se conservarán InnoDB y su capacidad transaccional.

Aún no está disponible para descarga, pero no deja de llamarme la atención la cantidad de movimiento que está habiendo en esa capa de la estructura típica de una aplicación. Las relacionales de toda la vida están en entredicho, y la tendencia es a simplificar, y con ello, a facilitar la extensibilidad.

Una charla sobre Drizzle. FAQ. Post sobre el estado actual y otro sobre el nuevo producto.

04 agosto, 2008

Ejecución de una función en segmentos

En Dreaming in Javascript muestran una forma de tratar con las funciones Javascript cuya ejecución lleva más tiempo del previsto y aparece un mensaje indicando que el navegador no responde y si se quiere detener el programa. La idea es detectar si el proceso está llevando más tiempo del previsto y usar la función setTimeout(nombreFuncion,0) para rellamar a la función y que continúe el trabajo pero empezando de nuevo la cuenta atrás para que aparezca el aviso. Una forma de detectar si el tiempo es excesivo sería comprobando el tiempo transcurrido a cada iteración del bucle. Para poder continuar con la ejecución de la función después del setTimeout, es necesario guardar los datos con los que se esté trabajando. Un buen lugar para hacerlo es la misma función. Para ello, se puede usar la sintaxis nombreFuncion.variable=valor que permite crear una variable persistente entre llamadas. Como ejemplo, en el blog proponen una función que calcula los factores primos de un número especificado y se prueba a llamar a la función con el número 100 000:

function findPrimes2(topCandidate) {
       var persist=arguments.callee;
       var tries=0;
       if (persist.candidate===undefined) {
           persist.candidate=2;
           persist.primes=[];
           persist.topCandidate=topCandidate;
       }
       keepTrying = true;
       while (persist.candidate <= persist.topCandidate && keepTrying) {
           trialDivisor = 2;
           prime = true;
           while (trialDivisor * trialDivisor <= persist.candidate) {
               if (persist.candidate % trialDivisor === 0) {
                   prime = false;
                   break;
               }
               trialDivisor++;
           }
           if (prime) {
               persist.primes.push(persist.candidate);
           }
           persist.candidate++;
           tries++;
           if (tries>1000) {
               keepTrying=false;
           }
       }
       if (keepTrying) {
           persist.candidate=undefined;
           alert(persist.primes.length);
       } else {
           setTimeout(persist,0);
       }
   }

findPrimes2(100000);

El nuevo Delicious

Via Socklabs Blog. Delicious es un sitio para compartir y guardar enlaces a páginas web clasificados por etiquetas, justo como mi proyecto indiza.com. El equipo de Delicious en Yahoo! ha trabajado duro durante más de un año para cambiar completamente el sistema a la versión 2.0. El rediseño es espectacular, simple pero también atractivo y ligero.

Antes se trataba de una enorme aplicación realizada en Perl sobre Apache y MySQL. La versión nueva basada en un sistema multi-capa tiene un poco de PHP y de C++ aderezado con Erlang (un lenguaje creado por la empresa de telecomunicaciones Ericsson orientado a la escalabilidad y que está cobrando auge últimamente). Simon Willison comenta que con el nuevo motor de búsqueda planea realizar antes sus búsquedas en él que en Google.

Últimos links en indiza.com