sábado, 25 de diciembre de 2010

Javascript orientado a objetos

Debido al gran auge de la web, últimamente han surgido numerosas librerías y tutoriales acerca de como programar javascript orientado a objetos.

No es difícil encapsular código javascript simulando que se está trabajando con clases.

function Article(title, body){
this.title = title;
this.body = body;
}

var a = new Article('titulo', 'noticia')

Incluso se puede conseguir visibilidad privada para los atributos de la 'clase' que elijamos.

function Article(title, body){
this.body = body;
var _title = title;
this.getTitle = function(){
return _title;
}
this.setTitle = function(title){
_title = title;
}
}

Sin embargo, en mi opinión todas estas aproximaciones conducen a escribir código javascript poco natural. Javascript fue pensado como un lenguaje de programación basado en prototipos y su flujo principal de ejecución es orientado a eventos.

Está basado en prototipos, la encapsulación, las 'clases' se obtienen a partir de la clonación de objetos y no de una estructura tan rígida como la orientación a objetos. Esto hace al lenguaje mucho más propicio para las tareas que fue pensado.

De la orientación a eventos del lenguaje han surgido proyectos muy interesantes como node.js, hay que tratar de aprovechar las bondades del lenguaje, no cambiarlas a través de capas de abstracción.

miércoles, 15 de diciembre de 2010

Logger en ruby

Similar al proyecto log4j existe para ruby una librería de logging para el depurado de aplicaciones, gestión de mensajes de error, etc.

El nombre de la librería es log4r, se distribuye como gema y es fácilmente personalizable.

Para usarla tan solo hay que instancia un objeto de la clase Logger. Para dicho objeto se pueden seleccionar distintos outputters (medio de salida), en el ejemplo se muestran los mensajes tanto por salida estándar como por UDP.

Posteriormente, para cada outputter se puede elegir un formatter (formato de la salida). En el ejemplo la salida por UDP será en el formato por defecto mientras que la salida estándar será en XML.

El ejemplo de uso de la librería.

require 'rubygems'
require 'log4r'
require 'log4r/formatter/log4jxmlformatter'
require 'log4r/outputter/udpoutputter'

include Log4r

logger = Logger.new 'mylog'

#Formatters
xmlformat = Log4jXmlFormatter.new

#Ouputters
stdout = Outputter.stdout
udpout = UDPOutputter.new 'udp', :hostname => "localhost", :port => 8888

stdout.formatter = xmlformat

logger.outputters = [stdout, udpout]


def debug(logger, txt)
logger.debug txt
end

def error(logger, txt)
logger.error txt
end


debug(logger, 'Mensaje de DEBUG')
error(logger, 'Mensaje de error')

Para más información se puede consultar la web oficial de log4r.

sábado, 20 de noviembre de 2010

Lectura de memoria entre procesos Windows

En todos los sistemas operativos modernos la memoria está protegida entre procesos.
Si un proceso accede o escribe en una posición de memoria no esperada no debe afectar a los demás procesos.

A pesar de este planteamiento, en Windows es posible leer o escribir zonas de memoria entre procesos, para ello están las funciones del API ReadProcessMemory y WriteProcessMemory.

El primer paso es encontrar el PID del proceso en el que estamos interesados y después debe obtenerse un handle con la función OpenProcess.

Para buscar el proceso destino hay varias formas, en este ejemplo se usa el nombre de la ventana visible del proceso.

#include <QtCore/QCoreApplication>
#include <windows.h>

DWORD getPIDByWindowName(WCHAR* name);

int main(int argc, char *argv[]){
QCoreApplication a(argc, argv);
BYTE buffer[300];
DWORD readed;
DWORD processID = getPIDByWindowName(TEXT("Calculadora"));
HANDLE procHandle = OpenProcess(0x0010, 0, processID);
ReadProcessMemory(procHandle, (void*)0x00951558, buffer, 50, &readed);
return a.exec();
}

DWORD getPIDByWindowName(WCHAR* name){
DWORD processID;
HWND windowHandle = FindWindowW(NULL, name);
GetWindowThreadProcessId(windowHandle, &processID);
return processID;
}

Gracias al uso de estas funciones del API se abre una nueva posibilidad de comunicación entre procesos, sin embargo, abre también un grave riesgo de seguridad. Entre otros usos, modificando la memoria de los procesos de antivirus o cortafuegos se pueden inutilizar dando una falsa sensación se seguridad.

martes, 16 de noviembre de 2010

Ejecución de tareas asíncronas en C++ con QT

En los programas con interfaz gráfica no deben ejecutarse tareas que puedan demorarse en el mismo hilo de la interfaz.
Esto ocurre muy a menudo si en el evento 'click' de un botón se hace una lectura/escritura de un fichero o una base de datos.

Con las librerías QT se puede solucionar de varias formas, una es creando un hilo (una clase que herede de QThread). Una forma aún más sencilla es crear un objeto QRunnable y hacer que el pool de QT lo ejecute en segundo plano.

Un ejemplo de lo segundo.

class AsynchrounousTask : public QRunnable{
protected:
QLabel *label;
public:
AsynchrounousTask(QLabel *label){
this->label = label;
}

void run(){
sleep(5); //long task;
label->setText("Done!");
}
};

Y para usarlo tan solo hay que hacer.

AsynchrounousTask *aTask = new AsynchrounousTask(ui->label);
QThreadPool::globalInstance()->start(aTask);

Aunque creamos un objeto con new no hay que preocuparse por su destrucción, al terminar su ejecución a través del pool se liberará de forma automática. Si preferimos que no se libere de forma automática tan solo hay que llamar al método 'setAutoDelete(false)'.

Ejecutando las tareas más pesadas de la aplicación de esta forma no se bloqueará la aplicación en ningún momento y siempre responderá a las nuevas peticiones que el usuario haga.

miércoles, 10 de noviembre de 2010

Compilación de ejecutable con Qt Creator

Cuando creamos una aplicación con Qt Creator en Windows es necesario incluir los ficheros dll de Qt para que la aplicación funcione correctamente.

En ocasiones este no es el comportamiento deseado, se puede generar un fichero ejecutable autónomo (sin necesidad de ninguna librería dll externa) ejecutando el siguiente comando:

qmake -nodepend -o Makefile project.pro

Si no se encuentra el programa qmake hay que añadirlo al PATH, la instalación por defecto de QT Creator no lo hace.
Una vez ejecutado el comando anterior, al compilar obtendremos un ejecutable con toda la funcionalidad incluida, sin necesidad de incluir ningún fichero dll.

domingo, 17 de octubre de 2010

Anidamiento de módulos en ruby

Tal y como ocurre en python con los decoradores, cuando se programa un módulo en ruby debería dejarse la puerta abierta a que no fuera el único.

En el siguiente ejemplo tenemos dos módulos (Printable y Serializable), ambos métodos se deben poder combinar en cualquier orden y pudiendo aparecer uno, ninguno o ambos.

La clave para que un mismo método se ejecute en la clase y en cada uno de sus módulos, es la llamada a super.

En otros lenguajes esto no sería correcto, puesto que los módulos Printable y Serializable no son superclase de la clase Test, pero en ruby, super no llama exactamente a la superclase, sino que repite el mismo método que se está ejecutando obviando la definición actual.

module Printable
def print_method
super
puts "I'm printable"
end
end

module Serializable
def print_method
super
puts "I'm serializable"
end
end


class Test
include Printable
include Serializable

def method_missing(method, *args, &block)
super if method.to_s != 'print_method'
end

def print_method
super
puts "I'm object of Test class"
end

end

t = Test.new
t.print_method

Con este planteamiento hay un problema añadido, al final de la cadena de llamadas a print_method estará la clase de la que hereda Test, y esta clase no tiene porqué tener implementado print_method.

Para solucionarlo en este caso se redefine el method_missing, cuando llegue el momento de ejecutar el método en alguna clase/módulo que no lo entienda, se corta la cadena de ejecuciones.

I'm printable
I'm serializable
I'm object of Test class

viernes, 17 de septiembre de 2010

Conversión implícita de tipos

Es común escribir nuevas clases que expandan a las básicas del lenguaje.

Uno de los problemas que nos podemos encontrar cuando hacemos esto es la conversión de tipos.

Si por ejemplo creamos una nueva clase para manejar cadenas, el código se llenará rápidamente de castings para convertir las cadenas nativas del lenguaje a nuestra implementación. Esto ocurre sobre todo en lenguajes fuertemente tipados.

C# provee una solución bastante elegante, la conversión implícita de tipos.

Para mostrar el uso de esta característica se muestra una clase con dos tipos, una cadena y un entero y sus declaraciones de conversiones implícitas.

public class MyClass
{
private string str { get; set; }
private int number { get; set; }

public static implicit operator MyClass(string s)
{
MyClass ms = new MyClass();
ms.str = s;
return ms;
}

public static implicit operator MyClass(int i)
{
MyClass ms = new MyClass();
ms.number = i;
return ms;
}

public string getStr()
{
return str;
}

public int getNumber()
{
return number;
}
}

Declarando un operador estático, implícito y público se consigue la sintaxis siguiente para la conversión de tipos.

MyClass ms1 = "hello";
MyClass ms2 = 2;

Console.WriteLine(ms1.getStr());
Console.WriteLine(ms2.getNumber());

En el ejemplo se puede ver que no es necesaria ninguna conversión, y se pasan tanto la cadena "hello" como el entero 2 a tipo MyClass.

domingo, 12 de septiembre de 2010

Extension methods en c#

En algunos lenguajes dinámicos como ruby las clases se denominan "abiertas".
Esto significa que a cualquier clase se le puede añadir nuevos métodos o funcionalidades en tiempo de ejecución.

Los lenguajes fuertemente tipados no suelen ofrecer tanta libertad, pero se disponen de otras herramientas.

En C#, se pueden definir clases parciales, lo que significa que se puede definir el comportamiento de la clase en varias etapas.

public partial class PartialClass
{
public static void method1()
{
Console.WriteLine("method1");
}
}
...
public partial class PartialClass
{
public static void method2()
{
Console.WriteLine("method2");
}
}

Manteniendo las clases como parciales en cualquier momento se puede añadir funcionalidad a una clase existente fuera de su definición original.

Este método es útil tan solo para las clases que programamos, pero si queremos extender una librería externa o las clases del propio lenguaje las clases parciales no son de gran ayuda.

C# tiene en cambio una posibilidad más interesante, los "extension methods".

public static class ExtensionMethods
{
public static string withDot(this string str)
{
return str + ".";
}
}
...
string str = "text ";
str.withDot();

Con el código anterior se le añade a la clase string el nuevo método (withDot).
Para hacer lo mismo sin "extension methods" habría sido necesario crear una nueva clase que heredara de string y añadirle el método withDot.

Gracias a los "extension methods" se puede evitar crear clases intermedias para extender funcionalidades de las ya existentes.

sábado, 28 de agosto de 2010

Implementación explícita de interfaces en C#

Por diversas razones como la colisión de nombres o simplemente por diseño, puede que necesitemos mayor granularidad para distinguir que método de que interfaz estamos definiendo.

Supongamos que tenemos el caso de una clase que implementa dos interfaces tal y como sigue:

public interface IInterface1
{
int method();
int method1();
}

public interface IInterface2
{
int method();
int method2();
}

public class ExampleClass : IInterface1, IInterface2
{
public int method() { return 1; }
public int method1() { return 1; }
public int method2() { return 2; }

}

En este caso, el método method está presente en las dos interfaces y lo definimos en la clase.

Si necesitáramos distinguir alguno de los casos se podría usar la implementación explícita de interfaces.

public class ExampleClass : IInterface1, IInterface2
{
public int method() { return 1; }
public int method1() { return 1; }
public int method2() { return 2; }

int IInterface1.method() { return 1; }
int IInterface2.method() { return 2; }

}


public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();

ExampleClass example = new ExampleClass();
IInterface1 i1 = (IInterface1)example;
IInterface2 i2 = (IInterface2)example;

MessageBox.Show("Interface 1: " + i1.method());
MessageBox.Show("Interface 2: " + i2.method());
}
}

Esto devolvería como resultados 1 y 2 respectivamente. Como vemos, a pesar de realizar la implementación explícita de ambas interfaces se sigue pudiendo implementar de la forma tradicional como caso base.

miércoles, 21 de julio de 2010

Internacionalización con QT

La librería QT está desarrollada de tal forma que las aplicaciones
que estén hechas usando su API pueden internacionalizarse de forma bastante
fácil.

En primer lugar todas las cadenas de la aplicación deben sustituirse por llamadas
a la función tr.

QObject::tr("cadena");

La cadena que pasemos a la función tr servirá de índice para las cadenas
definitivas en los distintos idiomas.

Después se debe añadir una entrada en el fichero de proyecto (.pro) con los ficheros
que se deben generar para cada idioma de las traducciones, con extensión .ts.

TRANSLATIONS = en.ts es.ts

Los ficheros se generarán al ejecutar el comando:

lupdate proyecto.pro

Estos ficheros .ts se pueden editar con QT Linguist, una vez introducidas todas las
traducciones, se pueden exportar mediante la opción Release, esto generaráa
unos ficheros .qm.

Posteriormente hay que crear un fichero de recursos que contenga los ficheros .qm
de traducciones.

Para obtener el idioma del equipo en el que se está ejecutándo la aplicación se puede
hacer lo siguiente

QString locale = QLocale::system().name();

Para que las traducciones se carguen hay que instanciar la clase QTranslator y pasársela
a la aplicación.

QTranslator translator;
translator.load(locale, ":/");
a.installTranslator(&translator);

La ruta ":/" se refiere al prefijo introducido en el fichero de recursos.

Tras estos pasos las cadenas de la aplicación aparecerán traducidas dependiendo del idioma
del equipo en el que se esté ejecutándo.

jueves, 15 de julio de 2010

Como implementar interfaces en C++

C++ por si solo no trata las interfaces como un concepto diferenciado. Sin embargo se puede trabajar con interfaces tipo Java o C# aprovechándose de la heréncia múltiple creando clases abstractas.

En el siguiente ejemplo las clases ClassA y ClassB implementan la interfaz Interface, para ello tan solo tienen que redefinir el método method.

class Interface{
public:
virtual int method(int param) = 0;
virtual ~Interface(){};
};

class ClassA : public Interface{
public:
int method(int param){return param+1;}
};

class ClassB : public Interface{
public:
int method(int param){return param+2;}
};

Todos los usos que se le dan normalmente a las interfaces siguen siendo válidos con esta aproximación, con una salvedad, si queremos pasar la interfaz como parámetro a una función normalmente se haría como sigue.

std::string function(Interface i){
std::string str;

int number = i.method(1);
if(number==2){str = "ClassA";}
else if(number==3){str = "ClassB";}

return str;
}

Sin embargo, si hacemos esos el compilador protestará con un error similar a: "cannot declare parameter 'i' to be of abstract type 'interface'".

¿Por qué?
Esto ocurre porque por defecto en C++ los parámetros se pasan por valor, el objeto 'i' es imposible de crear ya que es de un tipo abstracto, el compilador no puede instanciarlo.

¿Qué solución hay?
Pasarlo como referencia, con una definición como la siguiente.

std::string function(Interface &i)

Si queremos asegurarnos que el parámetro no se modifica, habría que pasarlo como referencia constante.

std::string function(const Interface &i)

Esto plantea un nuevo problema, generando un error de compilación similar a: "passing 'const Interface' as 'this' argument of 'virtual int Interface::method(int)' discards qualifiers".

No se puede llamar a una función no constante desde un objeto constante. Para solucionarlo los métodos de la interfaz deberían ser constantes, quedando como sigue.

class Interface{
public:
virtual int method(int param) const = 0;
virtual ~Interface(){};
};

class ClassA : public Interface{
public:
int method(int param) const{return param+1;};
};

class ClassB : public Interface{
public:
int method(int param) const{return param+2;};
};

lunes, 5 de julio de 2010

Definición de funciones parciales

La definición de funciones parciales (currificación) es una técnica de la programación funcional poco extendida.

A una función parcial con dos parámetros, se le puede pasar tan solo una variable, obteniendo como resultado de la ejecución otra función con una variable a la que ya se le a aplicado el primer parámetro. Por ejemplo, scala tiene una sintaxis muy simple para llevar a cabo esta técnica.

def function(x:Int)(y:Int) = x+y

val partial = function(3)_

partial(4)

Como resultado de la evaluación parcial (es obligatorio en scala acabarla con '_') se obtiene una función que solo necesita el segundo parámetro para ser evaluada.

Esta técnica puede servir para ahorrar código, modelar inyección de dependencia o reducir interfaces de un conjunto de funciones haciéndolas más sencillas.

miércoles, 30 de junio de 2010

Creación de servidores en javascript

Aunque javascript está diseñado para ejecutarse en el cliente al cargar páginas web, no está limitado a este ámbito.
Existe un proyecto llamado CommonJS que amplia la funcionalidad del lenguaje haciéndole poder interactuar con el sistema como un lenguaje más.

node.js es un framework para la creación de servidores que se apoya en la librería CommonJS.
Está construido completamente siguiendo la filosofía "event-loop" y todas las operaciones I/O se realizan de manera asíncrona para una buen aprovechamiento de la concurrencia del sistema.

Así pues, node.js permite crear servidores optimizados de forma sencilla desde un lenguaje dinámico como javascript, un ejemplo muy simple de un servidor creado con node.js es el siguiente:

var sys = require('sys');
var net = require('net');

var acc = 0;

net.createServer(function (socket) {
socket.setEncoding("utf8");
socket.addListener("connect", function () {
socket.write("Accumulator server\r\n");
socket.write("Accumulator value: " + acc + '\n');
});
socket.addListener("data", function (data) {
var input = parseInt(data);
if(!isNaN(input)){acc += parseInt(data);}
socket.write("Accumulator value: " + acc + '\n');
});
socket.addListener("end", function () {
socket.end();
});
}).listen(8888, "127.0.0.1");

Se puede consultar en mayor profundidad el API oficial.

miércoles, 16 de junio de 2010

Nuevos tipos de formularios en html5

Con el salto a la nueva versión de html se van añadir nuevos tipos de entradas posibles a los formularios.
Por ejemplo, crear un 'slider' para seleccionar un rango se limitará a dar el tipo range a un input.

<input type="range" min="0" max="100" step="2">

Este componente enriquece la interfaz de usuario, hay otros aún más útiles, por ejemplo el siguiente indica que la entrada debe ser de tipo numérico, esto puede ayudar a dispositivos móviles con pantallas reducidas a desplegar tan solo un teclado con números, aprovechando mejor el espacio.

<input required type="number" min="0" step="1" >

También sirve el tipo email para idénticos propósitos. Además de esta forma los navegadores pueden añadir mayor integración (si conocen que el tipo de entrada es email pueden sugerir los de nuestra libreta de direcciones).

Otro tipo de entradas muy comunes son las de fecha, en buscadores de reservas de hoteles, vuelos, etc. La mayoría de webmaster solucionan el problema de mostrar un calendario con javascript.
En html5 se deja este la responsabilidad de representar estos tipos de entradas a los navegadores, habiendo inputs de tipo date, month, week, time...

Para más información.

domingo, 13 de junio de 2010

Hot swapping en erlang

Hot swapping en un entorno con múltiples procesos distribuidos se refiere a la actualización de uno de esos procesos sin parar en ningún momento el sistema.

Si se encuentra algún error en el software, o se necesita añadir nueva funcionalidad, el proceso afectado encola las peticiones nuevas que van llegando, actualiza su código y con el nuevo código sigue atendiendo a las peticiones que tenía encoladas. Los demás procesos del sistema no notan nada de este cambio.

En muchas de las tecnologías usadas hoy en día, todo este proceso es bastante complejo, sin embargo, en erlang es trivial ya que lo soporta de forma nativa el lenguaje.

Supongamos dos procesos, uno que sirve datos.

-module(data).
-export([get/0, version/0]).

get() -> 42.

version() -> 1.

Y otro que los consume.

-module(consumer).
-compile(export_all).

start() -> spawn(fun() -> loop() end).

loop() ->
sleep(),
io:format("Value: ~p at version: ~p~n", [data:get(), data:version()]),
loop().


sleep() ->
receive
after 1000 -> true
end.

El proceso consumidor irá mostrando cada segundo los datos que le manda el otro proceso. En el momento que se necesite cambiar la funcionalidad del proceso creador de datos, simplemente se recompila y el consumidor el único cambio que notará es el valor que tienen los nuevos datos.

1> c(data).
{ok,data}
2> c(consumer).
{ok,consumer}
3> consumer:start().
<0.53.0>
Value: 42 at version: 1
Value: 42 at version: 1
Value: 42 at version: 1
Value: 42 at version: 1
Value: 42 at version: 1
...
c(data).
{ok,data}
Value: 43 at version: 2
Value: 43 at version: 2
Value: 43 at version: 2
Value: 43 at version: 2
...

En entornos críticos o en los que el sistema completo tarda mucho tiempo en arrancar, esto permite actualizar código sin que haya que mantener el servicio parado mientras se actualilza.

jueves, 10 de junio de 2010

Código Thread-Safe vs Código reentrante

Estos dos conceptos son habitualmente confundidos y, aunque están relacionados se corresponden a propiedades distintas.

Una función es thread-safe cuando se le puede llamar desde múltiples hilos concurrentemente, la ejecución terminará correctamente sin que unos hilos interfieran con otros.

Una función reentrante es aquella a la que se le pasa como parámetro todos los valores que usa, no utiliza ningún objeto global (variable global, singleton), no tiene efectos secundarios y no llama a ninguna función no reentrante.

Una función reentrante será siempre thread-safe, si no hace ningún cambio en el estado global de un programa no hay posibilidad que interceda con el código de otra hebra.

¿Y al contrario? Una función thread-safe no tiene porqué ser reentrante, ya que puede modificar el estado global del programa siempre que lo haga ordenadamente mediante exclusión mutua.

Una función reentrante cumplirá además con la transparencia referencial. Transparencia referencial es una propiedad que se cumple cuando, al cambiar una función con sus parámetros por el valor que devuelve, el programa se comporta de la misma forma.

Este tipo de funciones (reentrantes) tienen la ventaja de que se puede seguir su funcionamiento matemáticamente y que admiten memoization como optimización. Un ejemplo aquí.

domingo, 6 de junio de 2010

Ejecución de código remoto con ruby

Existe una librería llamada msgpack que permite la ejecución remota de código ruby (entre otros lenguajes), lo que más destaca de esta librería es su sencillez y la poca configuración necesaria para funcionar.

En un ejemplo cliente/servidor, el servidor es una instancia de una clase que contiene los métodos que queremos ejecutar de forma remota. Además de eso tan solo tenemos que elegir a qué clientes escuchamos y en qué puerto.

require 'rubygems'
require 'msgpack/rpc'

class RemoteServer
def printer(arg)
puts "Printing: #{arg}..."
return true
end
end

server = MessagePack::RPC::Server.new
server.listen('0.0.0.0', 8888, RemoteServer.new)
server.run

Un cliente que se conecte al servidor anterior sería el siguiente.

require 'rubygems'
require 'msgpack/rpc'

client = MessagePack::RPC::Client.new('127.0.0.1', 8888)
called = client.call_async(:printer, 'message')
result = called.get

La llamada call_async hace que se ejecute el método de forma asíncrona, si necesitamos el valor devuelto por la función será necesario llamar a get que se asegura de la terminación del método y de recoger el resultado.
También se puede ejecutar código de forma síncrona con call.

Además, la librería permite crear sesiones para reaprovechar las conexiones con el servidor.

require 'rubygems'
require 'msgpack/rpc'

session_pool = MessagePack::RPC::SessionPool.new
client = session_pool.get_session('127.0.0.1', 8888)
result = client.call(:printer, 'message')

jueves, 3 de junio de 2010

Solución al problema de la inclusión cíclica en C++

En aplicaciones complejas se puede dar el caso de que una clase(Class1) haga uso de otra(Class2), pero a su vez esta última haga uso de la primera.

En este caso estamos ante un problema de definición cíclica, para definir una clase se necesita la otra y viceversa. Se ejemplifica en el siguiente código.

#ifndef CLASS1_H
#define CLASS1_H

#include "class2.h"

class Class1{
void method(Class2* param);
};

#endif


#ifndef CLASS2_H
#define CLASS2_H

#include "class1.h"

class Class2{
void method(Class1* param);
};

#endif

Para solucionar este problema, podemos indicarle al compilador que la clase existe y será definida más adelante, así, aún teniendo dependencia cíclica se puede generar el código correctamente.
Para indicarselo al compilador tan solo hay que definir class Clase antes de usarla.

#ifndef CLASS1_H
#define CLASS1_H

#include "class2.h"

class Class2;

class Class1{
void method(Class2* param);
};

#endif


#ifndef CLASS2_H
#define CLASS2_H

#include "class1.h"

class Class1;

class Class2{
void method(Class1* param);
};

#endif

miércoles, 2 de junio de 2010

Web SQL en html 5

Con la llegada de html 5 los navegadores pondrán a disposición de los programadores web la tecnología web SQL.

Esta tecnología consiste básicamente en una base de datos local a los navegadores accesible desde javascript. Permitirá que las aplicaciones web puedan hacer mayor trabajo offline y sincronizarse cada cierto tiempo con el servidor.

El acceso a estas bases de datos se hace mediante SQL.
Para abrir una base de datos se necesita ejecutar lo siguiente.

function openDB(dbName){
var version = 1;
var db = window.openDatabase(dbName, version, dbName, 2*1024);
return db;
}

Una vez abierta la base de datos para ejecutar SQL podemos disponer de las siguientes funciones.

function executeSQL(db, sqlString, args){
db.transaction(function(t){
t.executeSql(sqlString, args);
});
}

function executeSQL(db, sqlString, args, callback){
db.transaction(function(t){
t.executeSql(sqlString, args, callback);
});
}

Se puede pasar opcionalmente un callback a la función executeSQL, es especialmente útil en las consultas para tratar el resultado. Un ejemplo de callback para consultas es showEntries definida más adelante.
Este es un ejemplo típico de uso de web SQL.

function insertEntry(db, name){
executeSQL(db, "INSERT INTO entries(name) VALUES (?)", [name]);
}

function selectAllEntries(db, callback){
executeSQL(db, "SELECT * FROM entries", [], callback);
}

function showEntries(t, rs){
var entry;

for(var i=0; i<rs.rows.length; i++){
entry = rs.rows.item(i);
alert(entry['name']);
}
}


var db = openDB("example");
executeSQL(db, "CREATE TABLE IF NOT EXISTS entries(id INTEGER PRIMARY KEY, name TEXT)", []);

for(var i=0; i<10; i++){
insertEntry(db, "test"+i);
}

selectAllEntries(db, showEntries);

martes, 25 de mayo de 2010

Modificar bases de datos en android

Casi todas las apliaciones android guardan información en bases de datos, el propio teléfono soporta nativamente SQLite3.

Las bases de datos se guardan en el directorio /data/data/nombre.paquete.programa/databases/
Para copiar una base de datos del teléfono al ordenador tan solo hay que hacer (tras tener el android SDK instalado).

adb pull /data/data/nombre.paquete.programa/databases/example_database.db .

Una vez en el ordenador se pueden hacer las comprobaciones que se necesiten con cualquier cliente sqlite3.

Para pasar de nuevo la base de datos modificada al móvil se puede hacer con el siguiente comando.

adb push example_database.db /data/data/nombre.paquete.programa/databases/

sábado, 22 de mayo de 2010

Functors en C++

Los functors se definen como 'objetos función'.
Son la evolución natural de los punteros a función de C, un ejemplo de la sintaxis para definir un functor es el siguiente.

#include <iostream>
#include <string>
#include <cmath>

using namespace std;

class PrinterFunctor{
private:
string msg;

public:
PrinterFunctor(string _msg){
msg = _msg;
}

void operator()(){
cout << msg << endl;
}
};


int main() {
PrinterFunctor pf("Printing from printer functor");
pf();

}

Para crear un functor simplemente hay que redefinir el operador (), tras eso podremos llamar al functor como si fuera una función más.

Con un functor podemos implementar una función 'resumible', es decir, una función que recuerde el estado anterior para producir el siguiente. Por ejemplo.

class PrimeGenerator{
private:
int currentPrime;

public:
PrimeGenerator(int _prime){
currentPrime = _prime;
}

bool isPrime(int n){
int root = (int) sqrt(n);

for(int i=2; i<root+1; i++){
if(n%i==0) return false;
}

return true;
}

int operator()(){
int n = currentPrime;

while(1){
n++;
if(isPrime(n)){
currentPrime = n;
return currentPrime;
}
}
}
};

Esta clase devolverá el siguiente número primo cada vez que la llamemos, si hacemos lo siguiente generará los 100 primeros números primos empezando por 5.

int main() {
PrimeGenerator primeGenerator(5);
for(int i=0; i<100; i++){
cout << primeGenerator() << endl;
}
}

domingo, 16 de mayo de 2010

Wingedbox


Este post es para anunciar la salida de un nuevo proyecto, wingedbox.

Es un proyecto lanzado por kikorb y por mí (javiyu). El concepto detrás de esta nueva web es compartir ficheros de una forma más ágil con tus amigos, no encontramos nada que encajara con nuestras necesidades así que decidimos hacerlo nosotros mismos.

Se le ha llamado "twitter de ficheros" de forma bastante acertada, ya que describe bastante bien la funcionalidad básica. Aún está en fase alpha pero realmente está teniendo muy buena acogida.

Pronto saldrá tanto el API público entre otras novedades, ya están disponible la visualización online de imágenes y fotos y el streaming de música.

Aún no tenemos buzón de sugerencias en la web, así que si tenéis algún tipo de duda o sugerencia podéis escribir un email tanto a kikorb como a mí.

sábado, 15 de mayo de 2010

Bloques with de python

En Java es muy común la combinación de bloques try catch finally para obtener/liberar recursos de forma segura.

En python hay otra forma más elegante de hacerlo.

class database_connection:
def __enter__(self):
print("Open database connection")
return 1
def __exit__(self, type, value, traceback):
print("Close database connection")

with database_connection() as db:
print(db)

Al definirnos una clase con los métodos __enter__ y __exit__ y ejecutarla en un bloque with se nos asegura que:

1) Al entrar al bloque se ha ejecutado el método __enter__.
2) Tanto si hay un error en el bloque with como si termina correctamente, los recursos serán liberados (llamada a la función __exit__).
3) Opcionalemente se puede devolver un valor para usarlo dentro del bloque (en este caso db), aunque no es obligatorio.

lunes, 3 de mayo de 2010

Web Storage, sessionStorage y localStorage en html 5

Con el nuevo estándar html 5 se ha introducido el concepto de web storage.

Mediante el objeto sessionStorage se puede guardar información relativa solo a la ventana actual, es decir, a diferencia de las cookies, aunque tengamos dos ventanas del navegador abiertas en una pagina del mismo dominio, la variable sessionStorage será única para cada ventana.
La sintaxis es muy sencilla, para guardar el email del usuario se puede hacer algo como lo siguiente.

sessionStorage.email='mail@sever.com'

Para recuperarlo después tan solo hay que ejecutar:

sessionStorage.email

Con el objeto localStorage se guarda información en local de forma permanente, entre ventanas del navegador, de forma global y por dominio. La sintaxis para utilizarlo es similar a la de sessionStorage.

sábado, 1 de mayo de 2010

Compilar a código ensamblador en formato intel con gcc

Aunque por defecto gcc produce código ensamblador con sintaxis AT&T al pasar la opción -S también es posible hacer que la salida sea con formato Intel.

Tan solo hay que ejecutar el siguiente comando.

gcc -S -masm=intel proc.c

Realizar las modificaciones que sean necesarias y después para hacer el enlazado.

gcc prog.s -o prog

sábado, 24 de abril de 2010

Ensamblador inline en código C

Para incluir código ensamblador en un programa escrito en C la sintaxis es la siguiente.

#include <stdio.h>

int main(){
int var1 = 1;
int var2;
int var3;

__asm__(
"inc %%eax \n\t"
"movl %%eax, %%ecx \n\t"
"inc %%ecx \n\t"
:"=a" (var2), "=c" (var3)
:"a" (var1)
);

printf("Value1: %d\n", var1);
printf("Value2: %d\n", var2);
printf("Value3: %d\n", var3);


return 0;
}

Los paréntesis se escriben dobles para escapar el carácter '%' ya que en C es un modificador de cadena.

Todas las líneas acaban en '\n\t' para que el código en ensamblador quede formateado igual que el resto.

Los registros no se usan con el nombre como tal para las entrada/salida, se usan alias del tipo "a=eax, b=ebx, c=ecx...".

En el primer apartado "=a" (var2), "=c" (var3) se les está diciendo que el contenido final de eax lo lleve a var2 y el contenido de ecx lo lleve a var3.

En el segundo apartado "a" (var1) se le dice que se comience el bloque copiando el valor de var1 a eax, actuará como entrada.

El compilador da por hecho que los registros usados para entrada/salida del bloque en ensamblador no los puede reutilizar, pero si se utilizan más registros se pueden poner en un tercer apartado de forma opcional.

El bloque ensamblador escrito antes, hará lo siguiente:

1. Copia el valor de var1 a eax.
2. Incrementa el valor de eax en 1.
3. Copia el contenido de eax a ecx.
4. Aumenta el valor de ecx en 1.
5. Copia el valor de eax a var2.
6. Copia el valor de ecx a var3.

martes, 20 de abril de 2010

Position Independent Code

El position independent code o código no dependiente de posición es aquel que se puede reubicar en memoria y aún así seguirá funcionando correctamente.

Por defecto, en Mac el código producido por gcc es PIC, pero se puede forzar a que produzca código no PIC con la opción -fno-pic.
Si tomamos por ejemplo el siguiente código en C.

#include<stdio.h>

void func(){
printf("Hello again\n");
}

int main(){
printf("Hello world\n");
func();

return 0;
}

Y lo compilamos como no PIC con la siguiente instrucción.

gcc -fno-pic -S program.c -o nopic.asm

Se obtiene.

.cstring
LC0:
.ascii "Hello again\0"
.text
.globl _func
_func:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $LC0, (%esp)
call _puts
leave
ret
.cstring
LC1:
.ascii "Hello world\0"
.text
.globl _main
_main:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $LC1, (%esp)
call _puts
call _func
movl $0, %eax
leave
ret
.subsections_via_symbols

Se puede ver que la cadena almacenada en la línea 3 se referencia en la línea 10 de forma absoluta. Si cambia la ubicación del programa en memoria LC0 seguirá referenciando a la misma posición, pero allí ya no estará la cadena que se esperaba.

Por el contrario, si dejamos al compilador con las opciones por defecto, producirá código PIC, quedando de la siguiente forma.


.cstring
LC0:
.ascii "Hello again\0"
.text
.globl _func
_func:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $20, %esp
call L3
"L00000000001$pb":
L3:
popl %ebx
leal LC0-"L00000000001$pb"(%ebx), %eax
movl %eax, (%esp)
call L_puts$stub
addl $20, %esp
popl %ebx
leave
ret
.cstring
LC1:
.ascii "Hello world\0"
.text
.globl _main
_main:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $20, %esp
call L6
"L00000000002$pb":
L6:
popl %ebx
leal LC1-"L00000000002$pb"(%ebx), %eax
movl %eax, (%esp)
call L_puts$stub
call _func
movl $0, %eax
addl $20, %esp
popl %ebx
leave
ret
.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
L_puts$stub:
.indirect_symbol _puts
hlt ; hlt ; hlt ; hlt ; hlt
.subsections_via_symbols

En esta ocasión se puede ver que en la línea 15 se carga la cadena, pero de forma relativa, usando la diferencia entre la posición actual y la de la cadena. Además, se puede ver que hay unas nuevas directivas al incluir la función puts.

¿Por qué puede preferirse la generación de código no PIC? Pues observando los ejemplos se puede ver que generar código no dependiente de la posición del programa requiere más instrucciones en ensamblador y por tanto mayor tiempo a la hora de ejecutarse.

lunes, 19 de abril de 2010

Paso de mensajes entre procesos en windows

En la plataforma Windows tanto para la comunicación entre procesos como para el manejo de eventos se usa un sistema de mensajes.

Una de las características del sistema de mensajes de Windows es no disponer de autentificación, se puede aprovechar este hecho para simular eventos en los programas que se están ejecutando y de esta forma controlarlos desde el API de mensajes.

Se puede por tanto manejar un programa de forma automática desde otro, con las posibilidades que ello ofrece. Orientándolo a la ingeniería inversa se puede hacer fuzzing a programas que tan solo admiten entradas desde la interfaz gráfica.

Supongamos que tenemos un programa cuya ventana principal se llama "Form1" y un botón con el texto "Boton" en el cual al hacer click en un botón muestra un mensaje.

...
private void button_Click(object sender, EventArgs e){
MessageBox.Show("Wow!", "Clicked", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
...

Podemos simular que hacemos click en ese botón si desde otro programa hacemos lo siguiente.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WFuzzing{
public partial class Form2 : Form{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string strClassName, string strWindowName);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SendMessage(int hWnd, uint Msg, long wParam, long lParam);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr parameter);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

public const int WM_LBUTTONDOWN = 0x0201;
public const int WM_LBUTTONUP = 0x0202;

public Form2(){
InitializeComponent();
}

private void fuzzbutton_Click(object sender, EventArgs e){
IntPtr wHandle = FindWindow(null, "Form1");
List<IntPtr> result = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(result);
EnumWindowsProc childProc = new EnumWindowsProc(EnumWindow);
EnumChildWindows(wHandle, childProc, GCHandle.ToIntPtr(listHandle));
}

private static bool EnumWindow(IntPtr handle, IntPtr pointer){
StringBuilder text = new StringBuilder(256); ;
GetWindowText(handle, text, text.Capacity);

if(text.ToString() == "Boton"){
long lngResult = SendMessage(handle.ToInt32(), WM_LBUTTONDOWN, 0, 0);
long lngResult2 = SendMessage(handle.ToInt32(), WM_LBUTTONUP, 0, 0);
}
return true;
}

}
}

Se le mandan dos mensajes, el primero el de hacer click con el ratón y el segúndo el de levantar el dedo del ratón.

Al ejecutar ese código el primer programa debería mostrar el mismo mensaje que si hacemos click en el botón.

De forma similar, se puede automatizar la búsqueda de fallos en programas de los cuales no disponemos del código fuente, tan solo manipulando la interfaz, rellenando campos de texto, activando y desactivando controles, todo de forma automática.

miércoles, 7 de abril de 2010

Metaprogramación en c#

Aunque c# no proporcione demasiadas ayudas sintácticas a la metaprogramación si que se pueden aprovechar sus estructuras y tipos de datos para generar métodos de fórma dinámica.

En el siguiente código hay un ejemplo.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Collections;
using System.Runtime.InteropServices;


namespace example1{
class Program{
[DllImport("msvcrt.dll")]
static extern bool system(string str);

static void Main(string[] args){
Dictionary<string, Action<string>> method = new Dictionary<string, Action<string>>();
Expression<Action<string>> exp;

for (int i = 0; i < 100; i++)
{
var number = i;
exp = (p => Console.WriteLine("Parametro: " +p+"\nMetodo numero: "+number));
method["print_" + i] = exp.Compile();

exp = (p => Console.WriteLine(p + number));
method["concat_" + i] = exp.Compile();
}

method["print_17"]("test");
method["concat_35"]("Concatenando el numero -> ");


system("pause");
}
}
}

En primer lugar se crea un diccionario llamado method para contener todas las funciones generadas automáticamente.

Luego, en el bucle se crean 200 métodos, tanto dependientes de parámetro como de su posición en el bucle, sin embargo, para esto es necesario un pequeño hack.
Se le asigna a number el valor del contador, creando un objeto en cada iteración, en caso contrario todos los métodos creados tendrán como valor de i el último que ha tomado en el bucle, es decir, 100.

martes, 6 de abril de 2010

Expresiones regular en C++ con boost

La mayoría lenguajes de programación modernos proporcionan la posibilidad de usar expresiones regulares de forma nativa desde el propio lenguaje, sin embargo, en C++ es necesario recurrir a alguna librería como Boost.Regex.

Boost.Regex ofrece la mayoría de funciones comunes de las expresiones regulares.

#include <iostream>
#include <string>
#include <boost/regex.hpp>

int main(){
std::string s = "BEGIN->Cadena_entre_delimitadores<-END";
std::string s2 = "Cadena de texto con 3 numeros para sustituir 1, 4 por incognitas";
boost::regex r("BEGIN->(\\w+)<-END");
boost::regex r2("\\d");
boost::smatch result;

if (boost::regex_search(s, result, r)){
for(int i=0; i<result.size(); i++){
std::cout << "Ocurrencia n " << i+1 << ": "<< result[i] << std::endl;
}
}
else{
std::cout << "Ninguna coincidencia" << std::endl;
}

std::cout << "---" << std::endl;
std::string number("X");
std::cout << "Cadena modificada con una expresion regular: ";
std::cout << boost::regex_replace(s2, r2, number) << std::endl;

}

Con regex_search se pueden encontrar coincidencias de una expresión regular r dentro de una cadena s. Como resultado también tendrá en cuenta los grupos de captura.

Con regex_replace se pueden hacer sustituciones, cambiando las ocurrencias encontradas en la cadena s2 según el patrón r2, sustituyéndolas por number.

Papra compilar es necesario incluir tanto los headers como la librería correspondiente, en mi caso.

g++ -lboost_regex-mt -I/opt/local/include/ -L/opt/local/lib/ regex.cpp -o regex

viernes, 19 de marzo de 2010

Programación de callbacks con Boost

Usando las librerías Boost.Function y Boost.Bind se pueden crear fácilmente callbacks en c++ sin necesidad de usar punteros a función.

Un ejemplo.

#include <boost/function.hpp>
#include <boost/bind.hpp>

#include <iostream>


using namespace boost;

class Example{
private:
int a;
public:
function<void(std::string)> callback;

void setA(int value){
a = value;
changeA();
if(callback){callback("setA");}
}

void changeA(){
a++;
if(callback){callback("changeA");}
}
};


void debug(std::string s){
std::cout << "Method called: " << s << std::endl;
}

int main(){
Example e;
e.callback = bind(&debug, _1);
e.setA(123);
}

Siguiendo el planteamiento anterior obtendríamos la cadena de llamadas a las funciones de la clase Example.

Si no establecemos el callback (en este caso se hace en la segunda línea de main) el comportamiento será el normal, sin embargo, en caso de necesidad se le puede hacer un bind al objeto que queramos con una función de debug.

La programación usando callbacks es especialmente útil en programación concurrente, para más información en la página de Boost.Function.

domingo, 14 de marzo de 2010

Usar OpenGL desde ruby

Es interesante poder crear demos o escenarios en 3D desde un lenguaje dinámico como ruby (cuando el rendimiento no sea un problema).

Hay unos bindings para opengl llamados ruby-opengl que nos permiten acceder directamente a la API de OpenGL desde ruby.

Os dejo un ejemplo (inspirado en los tutoriales de NeHe) para que os hagáis una idea de la sintaxis.

require 'rubygems'
require 'opengl'

require "gl"
require "glu"
require "glut"
require "mathn"

include Gl, Glu, Glut

window = ""

def init_gl_window(width = 640, height = 480)
glClearColor(0.0, 0.0, 0.0, 0)
glClearDepth(1.0)
glDepthFunc(GL_LEQUAL)
glEnable(GL_DEPTH_TEST)
glShadeModel(GL_SMOOTH)

glMatrixMode(GL_PROJECTION)
glLoadIdentity
gluPerspective(45.0, width / height, 0.1, 100.0)

glMatrixMode(GL_MODELVIEW)

draw_gl_scene
end

def reshape(width, height)
height = 1 if height == 0

glViewport(0, 0, width, height)

glMatrixMode(GL_PROJECTION)
glLoadIdentity

gluPerspective(45.0, width / height, 0.1, 100.0)
end

$color1_intensity = 0
$color2_intensity = 0
$color3_intensity = 0

$rotation = 0

def draw_gl_scene
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

glMatrixMode(GL_MODELVIEW)
glLoadIdentity
glTranslatef(0, 0, -6)

# Draw a triangle
glBegin(GL_POLYGON)
glColor3f($color1_intensity, $color2_intensity, $color3_intensity)
glVertex3f( 0.0, 1.0, 0.0)
glColor3f($color3_intensity, $color1_intensity, $color2_intensity)
glVertex3f( 1.0, -1.0, 0.0)
glColor3f($color2_intensity, $color3_intensity, $colo1r_intensity)
glVertex3f(-1.0, -1.0, 0.0)
glEnd

$color1_intensity += 0.0005 if($color1_intensity %gt; 0.5)
$color2_intensity += 0.0005 if($color2_intensity %gt; 0.5)
$color3_intensity += 0.0010 if($color3_intensity %gt; 1)

glutSwapBuffers
end

def idle
glutPostRedisplay
end

# Keyboard handler to exit when ESC is typed
keyboard = lambda do |key, x, y|
if(key == 27) then
GLUT.DestroyWindow($window)
exit(0)
end
end


glutInit
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)
glutInitWindowSize(640, 480)
glutInitWindowPosition(0, 0)
window = glutCreateWindow("Example")
glutDisplayFunc(method(:draw_gl_scene).to_proc)
glutReshapeFunc(method(:reshape).to_proc)
glutIdleFunc(method(:idle).to_proc)
glutKeyboardFunc(keyboard)
init_gl_window(640, 480)
glutMainLoop()

Quizá sería interesante aportar un grado más de abstracción para hacer aún más sencillo la elaboración de gráficos desde este tipo de lenguajes.

miércoles, 3 de marzo de 2010

Unit Testing en C++ con Igloo

La realización de test unitarios aún siendo una buena práctica de programación puede ser muy tediosa si no se utiliza alguna librería que nos descargue de trabajo.

Igloo para C++ nos provee de una API muy sencilla, además tiene la ventaja de que no necesita instalación ya que Igloo es simplemente un conjunto de ficheros de cabecera.

Lo único que necesitamos para usar Igloo es bajarnos la última versión y compilar nuestro test incluyendo sus cabeceras:

g++ tests.cpp -o tests -I/path/de/igloo/

Dejo un ejemplo de como quedaría un conjunto de test unitarios a una clase.

#include <igloo/igloo.h>
#include <stdio.h>
#include <stdlib.h>

using namespace igloo;

class Example{
private:
int atrib1;
int atrib2;

public:
Example(int a1, int a2){
atrib1 = a1;
atrib2 = a2;
}

int getAtrib1(){return atrib1;}
int getAtrib2(){return atrib2;}

static int sum(int n){
int result = 0;
for(int i=1; i<=n; i++){result+=i;}
return result;
}
};

TestFixture(Assertions){
TestMethod(ShouldHandleIntegerEquality){
Assert::That(Example::sum(5), Is().EqualTo(15));
}

TestMethod(ShouldHandleStrings){
Example e(5,6);
char c1[100];

sprintf(c1, "%d", e.getAtrib1());
std::string a1(c1);
sprintf(c1, "%d", e.getAtrib2());
std::string a2(c1);

Assert::That(a1, Is().Not().EqualTo(a2));
}
};

int main(){
return TestRunner::RunAllTests();
}

Al ejecutar el programa anterior obtendríamos la salida: Test run complete. 2 tests run, 2 succeeded, 0 failed

viernes, 19 de febrero de 2010

Smart pointers de la librería Boost

Una de las ventajas que tiene la programación en Java sobre C++ es la recolección de basura.

Cuando escribimos un programa en Java no nos tenemos que preocupar de liberar la memoria que vamos usando, hay un recolector de la máquina virtual que lo hace por nosotros. De esta forma se reduce el número de memory leaks y se facilita la programación.

En C++ sin embargo la gestión de memoria debe realizarla el desarrollador, proporcionando más potencia pero también dificultando el desarrollo.

Para facilitar la programación en este apartado, la librería Boost cuenta con un concepto llamado smart pointers que liberan de complejidad a la hora de gestionar la memoria al programador.

Por ejemplo, usando el tipo scoped_ptr.

#include <boost/smart_ptr.hpp>

class Example{
public:
int a;
};

void scoped_pointer(){
boost::scoped_ptr<Example> ptr(new Example);
}

void pointer(){
Example *ptr = new Example;
}


int main(){
while(1){
pointer();
}
}


Al ejecutar este programa se irá reservando memoria constantemente hasta agotar la memoria total del sistema, puesto que en ningún momento se libera.

Sin embargo, si se modifica la llamada pointer por scoped_pointer el programa se ejecutará de forma estable, dado que al terminar el método, el scoped pointer libera la memoria utilizada de forma automática.

Hay smart pointers con otras políticas de gestión de memoria, para elegir cual nos conviene en la documentación de boost se detalla cada uno.

domingo, 24 de enero de 2010

Profiling de peticiones en ruby on rails

Ruby es un lenguaje dinámico muy potente pero por ello también muy díficil de depurar en ocasiones. En ruby on rails con los named_scope, before_filter, plugins, gems, etc puede ser todavía peor.

Sin embargo, en los sistemas operativos que soportan DTrace tenemos una ayuda para encontrar los cuellos de botella de la aplicación, por ejemplo, usando el script que hay en: http://dl.getdropbox.com/u/478290/blog/dtrace/rb_linetime.d.

Simulo un before_filter muy lento que se ejecute para todas las request como éste:

22 def takes_too_long
23 i = 0
24 100.times{
25 100000.times{i+=1}
26 100000.times{i-=1}
27 }
28 end

Después arrancamos el servidor de ruby on rails y obtenemos su PID (vía passenger-status, ps, top...)

Ejecutamos:

sudo dtrace -s rb_linetime.d -p pid_del_servidor > request.log

Hacemos una petición a la aplicación ruby on rails, después paramos DTrace con Ctrl+C y en request.log podemos ver los ficheros ruby que se van cargando y cuanto tarda cada uno, en concreto, nos fijamos en las líneas:

FILE LINE COUNT AVG(us) SUM(us)
...

/Users/javiyu/projects/rails/prueba/vendor/rails/activesupport/lib/active_support/core_ext/module/introspection.rb 86 849 188 160330
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/mongrel-1.1.4/lib/mongrel/configurator 285 83 30374 2521066
/Users/javiyu/projects/rails/prueba/app/controllers/application.rb 26 600000 16 9690835
/Users/javiyu/projects/rails/prueba/app/controllers/application.rb 25 681051 16 11087871
/Users/javiyu/projects/rails/prueba/vendor/rails/railties/lib/commands/servers/base.rb 14 69 974199 67219750
....

Vemos que application.rb tarda mucho más de lo normal, e incluso detecta el número de línea en el que está el cuello de botella, en este caso la 25 y la 26.

lunes, 11 de enero de 2010

Obtención de información relativa al procesador

Para la generación de código optimizado puede ser necesario conocer sobre que tipo de procesador se está ejecutando nuestro programa y que instrucciones soporta.

La instrucción cpuid proporciona información relativa al procesador.
Por ejemplo.

#include <stdio.h>

typedef unsigned int uint;

void print_register_str(reg){
int i;

for(i=0; i<4; i++){
printf("%c", reg >> (i*8) );
}
}

void cpuid(uint *eax, uint *ebx, uint *ecx, uint *edx, uint service){
__asm__ (
"pushl %%ebx \n\t"
"cpuid \n\t"
"movl %%ebx, %1 \n\t"
"popl %%ebx \n\t"
: "=a" (*eax),
"=S" (*ebx),
"=c" (*ecx),
"=d" (*edx)
:"a" (service)
);
}

int main(){
uint eax, ebx, ecx, edx;

printf("VendorString: ");
cpuid(&eax, &ebx, &ecx, &edx, 0);
print_register_str(ebx);
print_register_str(edx);
print_register_str(ecx);
printf("\n");


cpuid(&eax, &ebx, &ecx, &edx, 1);
printf("MMX support: %d\n", (edx >> 23) & 1);
printf("SSE support: %d\n", (edx >> 25) & 1);
printf("SSE2 support: %d\n", (edx >> 26) & 1);
printf("HyperTransport: %d\n", (edx >> 28) & 1);
printf("SSE3 support: %d\n", (ecx) & 1);

return 0;
}

Este programa tiene como resultado para mi cpu.

VendorString: GenuineIntel
MMX support: 1
SSE support: 1
SSE2 support: 1
HyperTransport: 1
SSE3 support: 1


Se puede obtener más información específica, aquí vienen algunos ejemplos más: http://softpixel.com/~cwright/programming/simd/cpuid.php.