martes, 11 de enero de 2011

Json.Net 4.0 acerca el lado dinámico y estático de las aplicaciones web

Json

Json.Net es una librería de alto rendimiento para manejar el protocolos Json (JavaScript Object Notation) desde .NET.

Json es el mecanismo de comunicación más utilizado hoy día en aplicaciones web modernas. La revolución inicial de AJAX (Asynchronous JavasScript And XML) implicaba, como su nombre lo indica, intercambiar XML desde el browser y el servidor, manipulando el DOM de las páginas para refrescar datos, en lugar de volver a traer el HTML completo. Desde hace tiempo esto dejó de hacerse serializando a XML, pasando en cambio a Json porque es más compacto, lo que implica menos tráfico, pero también porque es muchísimo más JSON.parse (en JavaScript puro) o $.getJSON (en JQuery).

Sin embargo, volviendo a .NET, tradicionalmente la convivencia entre el mundo estático y el paradigma eminentemente dinámico que propone Json no fue sencilla. Existe dentro del framework el espacio System.Web.Script.Serialization que contiene un JavaScriptSerializer, pero utilizarlo es una tarea ardua y bastante propensa a errores.

Entre las alternativas abiertas, Json.Net es una de las más populares, y en su reciente versión 4.0 (release 1), aprovecha las nuevas características dinámicas del .NET Framework 4. Más que ninguna otra cosa, el uso de esta librería se simplificó enormemente a partir de aprovechar el nuevo tipo dynamic en .NET (que irónicamente, es un tipo estático más), y el agregado de LINQ to Json.

Veamos el uso de Json.Net con tipos dynamic:


dynamic value = new DynamicDictionary();

value.Name = "Juan Perez";
value.Enabled = true;
value.Roles = new[] {"Admin", "User"};

string json = JsonConvert.SerializeObject(value, Formatting.Indented);
// {
// "Name": "Juan Perez",
// "Enabled": true,
// "Roles": [
// "Admin",
// "User"
// ]
// }

¿No es elegante? Y mucho más sencillo que cualquier cosa tradicionalmente en .NET. Consumamos ahora el Json, a la inversa que en el ejemplo anterior:


dynamic newValue = JsonConvert.DeserializeObject(json);

string role = newValue.Roles[0];
// Admin

Finalmente, LINQ to Json permite (entre otras cosas) realizar consultas directamente sobre un resultado Json de manera simple y eficiente, como en este ejemplo:


var categories =
from c in rss["channel"]["item"].Children()["category"].Values()
group c by c into g
orderby g.Count() descending
select new { Category = g.Key, Count = g.Count() };

foreach (var c in categories)
{
Console.WriteLine(c.Category + " - Count: " + c.Count);
}

Algunas otras características de la nueva versión incluyen mejoras en la serialización binaria BSon, Json Schema, e inminentemente estará actualizado el paquete NuGet para instalar esta nueva versión desde Visual Studio directamente o desde la línea de comandos, manejando todas las dependencias que hubiese.

 

lunes, 10 de enero de 2011

Pycon 2011 - Del 9 al 17 de marzo en Atlanta, USA

PyCon 2011

La conferencia internacional de la comunidad Python de este año llega dentro de poco, a principio de marzo.

Llego tarde con el aviso, pero como siempre, la comunidad apoya financieramente a quienes quieren participar (y tienen buenas razones) pero no cuentan con la capacidad de costearse el pasaje o alojamiento.  Lamentablemente la presentación para solicitar ayuda financiera cerró a principio de este año, pero ténganlo en cuenta para los próximos años, porque al menos con una ayuda parcial muchos pueden llegar a tener la oportunidad.

Ya está disponible el cronograma completo de las charlas, y para quienes no puedan ir (imagino que la gran mayoría de los que están leyendo esto, incluyéndome a mi), recuerden que en general quedan los videos de toda la conferencia, como los del año pasado.

Como muestra para quien no quiere leer toda la lista, seleccioné las charlas que me parecieron más interesantes (a mi, obviamente):

Para quienes quieran seguir de cerca más detalles sobre la conferencia, pueden seguir su blog.

Y si algún lector asiduo de Code & Beyond asiste y tiene ganas de compartir notas con nosotros, basta con contactarme.

viernes, 7 de enero de 2011

Raros Lenguajes Nuevos: Scotch

Scotch

Siguiendo con la investigación sobre lenguajes experimentales o novedosos, hoy les presento Scotch, una creación de Ben Morris.

Ben empezó este proyecto de lenguaje como un ejercicio en Haskell, pero se entusiasmó con el resultado y sigue adelante, después de haberlo dejado abierto en GitHub para contribuciones de cualquiera.

Scotch es un lenguaje funcional que trata de mantener una sintaxis minimalista y expresiva, y agrega algunas características particulares a gusto de su creador:

La asignación es siempre no estricta (lazy), de manera que si definimos "a = b", no estamos pasando valores, sino asignando una expresión. Si luego decimos que "b = 42", al inspeccionar el resultado de "a", se va a evaluar la secuencia y obtendremos 42.

A diferencia de Haskell mismo, Scotch no es puro, y se pueden definir variables que mantengan estado, por lo que no queda libres de efectos colaterales como en lenguajes funcionales puros; también es débilmente tipado, lo que implica que podemos sumar números y strings, por ejemplo, y en lugar de dar error hace conversiones implícitas (siempre que pueda).

Otra característica interesante es la resolución implícita en base a reconocimiento de patrones. Por ejemplo, para definir una función que calcule el factorial de un número, se hacen dos definiciones, una genérica y una específica:

fact(n) = n * fact(n-1)
fact(0) = 1

La primera línea es la definición recursiva clásica, pero por si sola tiene el problema de que nunca terminaría, por lo que se puede definir el caso particular para cuando sea llamada con 0, de manera que en lugar de seguir llamándose a sí misma devuelva 1.

Casi toda la librería de clases está basada en este mecanismo, utilizando recursividad de cabeza y cola (head/tail) y utilizando patrones para manejar los casos límites donde debe cortarse la recursión.

Como casi todos los lenguajes funcionales, permite aplicación parcial y currying, como en este ejemplo:

apply(f, x) = f(x)
add(x, y) = x + y
apply(add(10), 20)

Aquí "apply" se define como la ejecución de una función que recibirá "x" como parámetro. La función "add" recibe dos parámetros y los suma, pero podemos aplicarla parcialmente como en el caso final, utilizando "apply".

También tiene soporte para hilos de ejecución livianos (lightweight threads), o sea que no son hilos reales del sistema operativo, sino implementados por el lenguaje mismo (en este caso utiliza los que provee Haskell).

Finalmente, el autor agregó Tipos de Datos Algebraicos (ADTs) que son como objetos livianos sin definición de clase, y funciones anónimas (lambdas).

La gracia principal de ste intérprete es que la implementación es muy pequeña y es un buen ejercicio tanto de implementación de un lenguaje como de Haskell mismo.

jueves, 6 de enero de 2011

Videos: Previews de Surface 2.0 y Android 3.0 (Honeycomb)

CES 2011

Durante la CES (la conferencia anual de electrónica para consumidores) que arrancó ayer, hubo unos cuantos anuncios ya, y algunas novedades ya dan vueltas por la red.

Microsoft pesentó la segunda versión de su dispositivo Surface, que ahora es muchísimo más fino ya que no usa más cámaras internas para capturar lo se apoya sobre la pantalla, sino que usa una tecnología en la que cada pixel es un sensor independiente. Esto permite usarlo no sólo como mesa, sino también como kiosko, más parecido a un televisor.

Google hara varios anuncios también, y ya tenemos al menos un video que muestra algunas características de la próxima versión de Android, que notarán orientado a mejorar la experiencia en tabletas además de teléfonos. Es interesante notar que algunas cosas como Maps en 3D y StreetView ya están disponibles hoy, aunque no con la misma velocidad que en el dispositivo del video.

Les dejo los videos de Surface y Android para que disfruten e imaginen aplicaciones:

 

miércoles, 5 de enero de 2011

Probando aplicaciones web con Zombie.js

http://www.flickr.com/photos/tohoscope/5086711384/Probar aplicaciones web modernas, con mucho scripting del lado cliente, es cada vez más complejo. El hecho de que la interfaz de usuario cambie dependiendo de las interacciones sin necesidad de pasar por el servidor genera la necesidad de realizar pruebas sobre el lado cliente.

El problema de esto es que la mayor parte de las herramientas para efectuar este tipo de pruebas requiere de una instancia de un browser real, lo que genera una dependencia fuerte y sobre todo, implica que cada prueba tarde más porque un browser demora un montón de tiempo en cargar y dibujar los elementos y tiene en cuenta montones de cosas que en realidad no necesitamos en la mayoría de los escenarios para hacer pruebas automatizadas.

Zombie.js se llama así porque es un entorno de prueba headless (sin cabeza; en realidad sin browser), y es muy rápido, además de brindar un API muy cómoda para escribir las pruebas.

La plataforma hace uso nuevamente de las ventajas de Node.js (más detalles en un post anterior) para recrear el entorno de un browser, incluyendo el DOM y características de HTML5, pero sin la necesidad de dibujar realmente nada, lo que le permite alcanzar velocidades totalmente diferentes.

Para lograr este entorno, Zombie combina varias librerías abiertas como JSDOM para emular el DOM, HTML5 para parsing, Sizzle para los selectores CSS y AJAXSLT para el soporte a XPath. Y el proyecto a su vez, también está abierto a quien quiera meter mano, alojado en GitHub.

Veamos un brevísimo ejemplo de cómo instanciar el entorno de un browser, navegar a una página, identificarse y verificar que la operación sea exitosa al llegar a una siguiente página de bienvenida.

var zombie = require("zombie");
var assert = require("assert");


// Carga la página desde el localhost
zombie.visit("http://localhost:3000/", function (err, browser) {


  // Completa email y password y confirma el formulario
  browser.
    fill("email", "zombie@underworld.dead").
    fill("password", "eat-the-living").
    pressButton("Sign Me Up!", function(err, browser) {


      // Al procesar el form, ve si fue a la página correcta
      assert.equal(browser.text("title"), "Welcome To Brains Depot");
    })
});

Como se ve, el API es muy sencilla y natural, y como siempre en Node, no hay llamadas bloqueantes; todo lo que pasa se maneja con callbacks, lo que hace también que correr una batería importante de pruebas sea más rápido en total, facilitando la ejecución más frecuente, lo que siempre eleva la calidad del proceso de desarrollo.