Monthly Archives: May 2009

You are browsing the site archives by month.

Visualización de la documentación de todas las gemas instaladas

La documentación de las gemas de ruby se genera a partir del código fuente mediante rdoc. Después de eso puedes optar por ver individualmente cada una o usar gem server.

Para poder mejorar todo esto podemos usar par de útiles herramientas: (1) la plantilla para rdoc, hanna; y (2)bdoc como alternativa a gem server para visualizar la documentación.

Hanna es una plantilla para rdoc que mejora notablemente el formato por defecto. Podemos ver la diferencia fácilmente, por ejemplo, en la documentación de rspec con el formato típico vs la documentación hecha con hanna. La instalación es simple:

$ sudo gem sources -a http://gems.github.com
$ sudo gem install mislav-hanna

Para que a partir de ahora se generar la documentación con esta plantilla, puede añadir a tu .gemrc la siguiente línea:

rdoc: --inline-source --line-numbers --template=hanna

Y para convertir la documentación de todas tus gemas instaladas, puedes hacer algo como esto:

$ sudo gem list | awk '{print $1}' | xargs sudo hanna --gems

Por otro lado, gracias a bdoc podremos navegar fácilmente entre todas las documentaciones.

$ sudo gem install manalang-bdoc
$ bdoc

bdoc
Ejecutando bdoc se nos abrirá en nuestro navegador por defecto listo para poder leer la documentación y poder movernos fácilmente entre las diferentes gemas (y versiones). Muy útil.

Librería de logging para C++, boost::logging

En C++ tienes diversas librerías de logging, la mayoría son clones de log4j realmente, u otras con un estilo diferente bastante interesante; pero como suele ser costumbre en el mundo C++, tienes una alternativa relacionada con las librerías boost (en realidad boost::logging no es de boost oficialmente, pero es más que probable que en el futuro lo sea) que suele ser la ganadora por méritos propios.

Estoy hablando de la implementación de John Torjo. Muy flexible a la hora de configurarla unido a un uso trivial de la misma (como tiene que ser, tampoco es que, la labor de logging, sea algo muy complejo que digamos…). Para conocer todos los detalles puedes leerte la extensa y útil documentación, aunque de primeras puede ser un tanto compleja debido a nuevos conceptos que se usan a diestro y siniestro.

Principalmente debemos de conocer dos cosas:

  • Qué tipo de filtro queremos: el cual será el encargado decidir si un mensaje se escribe o no, dependiendo tanto de si el logging está activado, como si cumplimos la restricción de nivel (debug, warn, error, etc…)
  • Qué tipo de log queremos: ¿cómo debe de ser el formato de salida?, ¿cuál es la salida/s? ¿cómo será su comportamiento?.

Una vez definido esto, podemos escribirnos un par de ficheros en los cuales definiremos el log que podrá ser usado desde cualquier parte de la aplicación, incluyendo el header, y siempre y cuando se haya inicializado previamente.

#ifndef __LOGGING_HPP__
#define __LOGGING_HPP__
 
#include <boost/logging/format_fwd.hpp>
 
using namespace boost::logging;
using namespace boost::logging::scenario::usage;
 
typedef use<
    filter_::change::single_thread, // how often does the filter change?
    filter_::level::no_levels,      // does the filter use levels?
    logger_::change::single_thread, // how often does the logger change?
    logger_::favor::correctness     // what does the logger favor?
  > finder;
 
BOOST_DECLARE_LOG_FILTER( g_log_filter, finder::filter )
BOOST_DECLARE_LOG( g_log, finder::logger )
 
#define L_ BOOST_LOG_USE_LOG_IF_FILTER( g_log(), g_log_filter()->is_enabled() )
 
void initialize_logs();
 
#endif // __LOGGING_HPP__

Aquí acabamos de declarar un log, sin niveles, para una aplicación simple sin usar un thread separado para el logging. Para ver otras alternativas puedes echarle un ojo a los namespaces boost::logging::scenario::usage::filter_ y boost::logging::scenario::usage::logger_.

Finalmente solo nos quedaría inicializar el log (o logs, recuerda que nada te impide tener tantos como quieras):

#include "logging.hpp"
#include <boost/logging/format_ts.hpp>
#include <boost/thread/xtime.hpp>
 
BOOST_DEFINE_LOG_FILTER( g_log_filter, finder::filter )
 
BOOST_DEFINE_LOG( g_log, finder::logger )
 
void initialize_logs()
{
  g_log()->writer().add_formatter( formatter::idx(), "[%] "  );
  g_log()->writer().add_formatter( formatter::time("$hh:$mm.$ss ") );
  g_log()->writer().add_formatter( formatter::append_newline() );
 
  typedef detail::flag<destination::file_settings> flag;
  destination::file_settings file_settings;
  file_settings.initial_overwrite = flag::t<bool>( &file_settings, true );
  g_log()->writer().add_destination(
      destination::file( "app_debug.txt", file_settings )
    );
  g_log()->writer().add_destination(
      destination::cerr
    );
 
  g_log()->turn_cache_off(); // for showing output immediately
  g_log()->mark_as_initialized();
}

Aquí tenemos que hacer la definición del log y del filter de la misma forma que hemos hecho su declaración anteriormente. Definimos el formato de salida como más nos guste y finalmente solo nos queda indicar dónde se deben de escribir los mensajes. Se puede tener varios destinos, aunque básicamente podemos usar desde ficheros hasta cualquier stream, pasando por las salidas estándar (fíjate en los typedef de boost::logging:destination).

Una cosa importante que merece la pena mencionar es la llamada al método turn_cache_off(), especialmente importante si usas una salida a consola, pues por defecto el logging se cachea y solo se escribe al destino cada cierto tiempo, por lo que si monitorizas el log en tiempo real es crucial desactivar esta caché.

De esta forma, ya tendremos en cualquier parte de nuestro código donde incluyamos la declaración una macro L_ (o como la hayamos definido) lista para ser usada:

L_ << "Here we are";
 
unsigned int n = 42;
L_ << "The meaning of life is " << n;
 
L_ << boost::format( "We can even use the awesome %s library versión %d.%d.%d" ) 
    % "boost::format"
    % ( BOOST_VERSION / 100000 )
    % ( ( BOOST_VERSION / 100 ) % 1000 )
    % ( BOOST_VERSION % 100 );

Cómo ver por Internet la F1 de forma precisa (y sin anuncios)

Las retransmisiones de LaSexta de la Formula 1 dejan bastante que desear, sobretodo cuando se refiere a las carreras de los domingos. Algunos aspectos negativos son estos:

  • Calidad de imagen pésima. En 4:3 en vez de 16:9
  • Mucha, mucha, muchísima publicidad. Durante la carrera, así a ojo, diría que te tragas alrededor de 30minutos de publicidad perfectamente.
  • Comentarios penosos, subjetivos y sin calidad (excepto Pedro De La Rosa obviamente) por parte de Antonio Lobato y Víctor Seara (difícil decidirse cual de ellos es más ignorante).
    • No paran de confundirse y decir estupideces cuando se refiere al futuro de la carrera, solo entrando en razón cuando De La Rosa pone las cosas claras.
    • No retransmiten la carrera, comentan las acciones que pasan en función a cómo pueden llegar a afectar a un único piloto, a pesar de existir, por lo normal, 19 más.
    • Se centran en acontecimientos irrelevantes, y la mayor parte de las veces, mal; olvidándose del transcurso real de la carrera.
  • La solución es bastante simple, sobretodo si tienes alguna forma cómoda de ver tu ordenador en una pantalla de televisión. Por una parte necesitamos (1) una forma precisa de poder conocer el transcurso de la carrera, y por otra necesitamos (2) una imagen y, no está de más, algunos comentaristas que sean competentes en su trabajo. Para solucionar el primer punto tenemos el fantástico live timing de formula1.com, en el cual podemos ver los tiempos en tiempo real de todos los pilotos, sector a sector. Y para el segundo punto, tenemos la retransmisión online de la cadena catalana tv3. El resultado será algo como esto:

    Formula 1 online: Tv3 y Live timing de f1.com

    Formula 1 online: Tv3 y Live timing

    Las únicas “desventajas” de este método son:

    • Comentarios en catalán: pero realmente es muy fácil de seguir (si sabes español claro), y eso que yo soy un negado para los idiomas
    • Resolución inferior al TDT: la resolución online no es nada espectacular, pero dado que no lo vamos a ver a pantalla completa, es más que suficiente para poder leer las letras y verlo de forma correcta.
    • Retraso de 20seg.: la TDT en verdad tiene también un retraso respecto a la realidad, de unos 3-5 segundos (lo puedes comprobar con el live timing) en este caso, estos 20segundos no es un problema tan grande puesto que de esta forma te da tiempo a analizar la evolución de los tiempos y luego ver su “resultado” en la imagen. Se podría decir que la imagen va a ir “1 sector” atrasada, lo cual viene hasta bien.

    Personalmente ganan las ventajas respecto a las desventajas, por lo que después de haber probado este método, para seguir este último Gran Premio de España, creo que repetiré para los próximos 12 de esta temporada.

Repositorios para versiones “antiguas” de Ubuntu

Ubuntu tiene un ciclo de desarrollo realmente pequeño, cada 6 meses tenemos una nueva versión, cada una de estas versiones tiene un periodo de mantenimiento asegurado que suele ser de únicamente año y medio, salvo las versiones LTS (hasta ahora Dapper y Hardy) que lo amplían hasta los 5 años.

Esto significa que para las versiones no soportadas se dejarán de publicar nuevos paquetes y se eliminarán de los repositorios oficiales. Lo cual viene a decir que apt-get deja de ser útil.

Afortunadamente, todos los paquetes de estas versiones los podremos seguir usando si cambiamos nuestro sources.list para que apunte a old-releases.ubuntu.com donde tendremos todos los paquetes para versiones antiguas.

Por ejemplo, para gutsy (la última que se ha dejado de soportar desde la salida de jaunty), nuestro sources.list sería algo como esto:

deb http://old-releases.ubuntu.com/ubuntu/ gutsy main restricted universe multiverse
deb-src http://old-releases.ubuntu.com/ubuntu/ gutsy main restricted universe multiverse

deb http://old-releases.ubuntu.com/ubuntu/ gutsy-updates main restricted universe multiverse
deb-src http://old-releases.ubuntu.com/ubuntu/ gutsy-updates main restricted universe multiverse

deb http://old-releases.ubuntu.com/ubuntu gutsy-security main restricted universe multiverse
deb-src http://old-releases.ubuntu.com/ubuntu gutsy-security main restricted universe multiverse

deb http://old-releases.ubuntu.com/ubuntu/ gutsy-backports main restricted universe multiverse
deb-src http://old-releases.ubuntu.com/ubuntu/ gutsy-backports main restricted universe multiverse

Habilitar ctrl+alt+backspace en Ubuntu

En Ubuntu jaunty, alguien tuvo la grandiosa idea de desactivar este útil atajo de teclado para reiniciar las X. Podemos activarlo de nuevo desactivando la opción DontZap en la sección ServerFlags del /etc/X11/xorg.conf:

Section "ServerFlags"
    Option    "DontZap"    "no"
EndSection

Otra forma incluso más simple, es usar una aplicación precisamente para esta labor:

$ sudo aptitude install dontzap
$ sudo dontzap -d

True Blood, se acerca la segunda temporada

La segunda temporada de esta peculiar serie, con el inconfundible sello del magnífico guionista Alan Ball, creador de Six feet under, comenzará el 14 de junio.