Notación Húngara: Una convención de .NET y Delphi

Como muchos sabéis, porque lo he comentado por aquí alguna vez, las prácticas del ciclo de FP las hice en una empresa que trabajaba en .NET y allí tuve mi primera experiencia con la llamada Notación Húngara. Esta fue creada por el programador húngaro Charles Simonyi, famoso por haber sido el padre de Bravo (el primer editor WYSIWYG) y uno de los responsables de Micosoft Office.

Aunque en Delphi no acabó de tener éxito, la notación húngara sí ha sido muy utilizada dentro de los desarrollos de la propia Microsoft. Dicha notación consiste en añadir antes del nombre de las variables uno o varios caracteres que indican su tipo. Esta técnica era muy útil hace años, si bien en la actualidad tiene muchos detractores, dado que actualmente es sencillo conocer el tipo de una variable sin tener que leerla en su declaración, por lo que se considera que esta notación sólo añade complejidad a la hora de programar.

Los prefijos a usar más habituales son:

  • a: Array
  • b: Booleano
  • by: Byte
  • c: Caracter de un byte
  • d: Tipo numérico de alta precisión (double o float)
  • dw: Tipo numérico de alta precisión
  • e: Evento o enumeración
  • f: Puede ser función o flags
  • fn: Función
  • g: Tipo delegado
  • h: Puede ser Hashtable o Handle
  • hdc: Handle a un contexto de dispositivo
  • hwnd: Handle a un contexto de ventana
  • i: Entero
  • ID: Identificador
  • l: Entero largo, de 32 bits. También puede ser ‘lock’, para definir objetos de control tipo candado
  • lbl: Objeto label
  • lp: Puntero a entero de 32 bits
  • lpfn: Puntero a una función que devuelve un entero largo
  • lpsz: Puntero a una función que devuelve una cadena terminada en cero
  • n: Entero de 16 bits o tipo enumerado
  • o: Objeto
  • p: Puntero
  • pt: Coordenadas empaquetas en un entero de 32 bits
  • rgb: Valor de color rgb empaquetado en un entero de 32 bits
  • s: Cadena de texto
  • sz: Cadena de texto terminada en cero
  • t: Variable tipo struct
  • txt: Caja de texto
  • v: Variable
  • w: Entero de 16 bits
  • x: Coordenada x.
  • y: Byte. También puede ser una coordenada y.

Otra de las cosas que se achaca a esta nomenclatura es la inexistencia de un estándar claro, lo que puede llevar a confusiones a la hora del mantenimiento del código.

El patrón Registry (y su aplicación en PHP)

Volvemos a los patrones de diseño tras un par de artículos de otra índole, y lo hacemos con Registry. La idea de este patrón es que nos permita utilizar los objetos y variables registrados en cualquier nivel de la aplicación sin necesidad de duplicarlos. Es decir, en la práctica nos permitiría usar cualquier objeto como si fuera un Singleton.

La idea de este patrón es crear una clase que tenga un array donde guardar los objetos registrados y una serie de métodos: uno que añada los objetos al array, otro que compruebe su existencia para evitar duplicaciones, otro que devuelva el objeto pasándole su clave, uno que borre el objeto recibiendo la clave y finalmente uno que limpie el array de la clase.

Pasado a código, PHP como siempre, la estructura sería la siguiente:

    <?php      
    class Registry  
    {  
        /** 
         * Registra variables y objetos         
         */  
        static private $registry = array();  
      
        /** 
         * Método que añade objetos
         * Recibe el objeto (por referencia) y la clave
         * Devuelve un booleano para confirmar si se ha insertado
         * o si en cambio estaba duplicado.
         */  
        static public function add($key, &$elemento)  
        {  
            if (!self::exists($key)) {  
                self::$registry[$key] = $elemento;  
                return true;  
            } else {  
                return false;  
            }  
        }  
      
        /** 
         * Función que comprueba la existencia de una clave.
         * Devuelve un booleano confirmando si existe o no.
         */  
        static public function exists($key)  
        {  
            return array_key_exists($key, self::$registry);  
        }  
      
        /** 
         * Función que devuelve un item dada la clave          
         */  
        static public function get($key)  
        {  
            if (self::exists($key)) {  
                return self::$registry[$key];  
            } else {  
                return null;  
            }  
        }  
      
        /** 
         * Elimina una entrada recibiendo su clave y devuelve confirmación.
         * Si la clave no existe devuelve false.
         */  
        static public function remove($name)  
        {  
            if (self::exists($name)) {  
                unset(self::$registry[$name]);
                return true;  
            } else {
                return false;
            }  
            
        }  
      
        /** 
         * Limpia el registro totalmente.         
         */  
        static public function clear()  
        {  
            self::$registry = array();  
        }  
    }  
    ?>  

El ejemplo es una estructura muy básica, puedes ampliarlo con filtros varios, control de errores y demás, pero la idea del esqueleto de este tipo de clase.

Ale, a disfrutarlo.

Actualizar Ubuntu 12.10 a 13.04

Cuestión sencillita ¿quieres actualizar tu Ubuntu 12.10 al recién salido 13.04 (Raring Ringtail)? Lo normal es que el propio Ubuntu te lo pregunte, pero puede ser que no ocurra así.

Bueno, pues lo primero es tener el equipo con una conexión a internet estable. Si es así basta con este comando:

$ sudo do-release-upgrade -d
logo ubuntu
Ubuntu 13.04

Tras esto comprobará la existencia de paquetes nuevos que instalar. Los verificará todos, te dará una estimación del tiempo necesario y te pedirá confirmación. Acepta (escribe una s y pulsa enter), espera a que termine y reinicia.

Y con esto, listo calixto.

Patrón MVC y PHP

Cierto es que este mes he estado poco activo en cuestiones bloggeras, pero ya me tenéis de vuelta con el tema de los patrones de Diseño, en este caso con el popular MVC (Model/View/Controller o Modelo/Vista/Controlador).

La idea del patrón MVC es separar en tres capas los datos (model), la interfaz de usuario (view) y la lógica de negocio (controller). Esto permite una mayor reutilización de componentes, facilita la modificaciones del aspecto del programa/web sin tener que tocar el funcionamiento y simplifica el mantenimiento. Funciona de forma «triangular», es decir, cada capa envía información a una y la reciba de la otra.

El modelo sería la representación de la información y se encargaría de gestionar el acceso, adición y modificación de los mismos (operaciones CRUD). A nivel de interacción con los otros componentes enviaría a la vista los datos que tienen que ser mostrados y recibiría desde el controlador las peticiones de acceso y manipulación.

La vista sería, como su nombre indica, lo que se ve en pantalla. Además de mostrar los datos al usuario le permite interactuar con ellos. La vista recibe del modelo los datos a mostrar y permite al usuario comunicarse con el controlador a través de sus objetos.

Finalmente el controlador, trabajaría como puente entre la vista y el modelo, recibiendo las peticiones del usuario a través de la primera, realizando las labores de transformación necesarias y realizando finalmente las peticiones al modelo.

Aunque el MVC nació originalmente (allá por los años 70) para aplicaciones de escritorio, el desarrollo de la web dinámica hizo que fuera adoptado como patrón para diseñar la arquitectura de muchos sitios web. Existen múltiples frameworks para diversos lenguajes que permiten implementar el MVC a la arquitectura web. En el caso de PHP hay gran variedad, pero desde aquí vamos a destacar cuatro de ellos, todos software libre:

  • Zend Framework: Dado que Zend es la empresa con más peso en el mundo de PHP, comenzaremos con su framework. He de decir que hasta la versión 1.9 existen muchas quejas al respecto de su rendimiento, pero a partir de la versión 2 se reescribió el código para lograr aligerarlo. Está bajo licencia BSD, por lo que su uso es cercano al dominio público.
  • Symfony: Creo que a día de hoy es el framework más utilizado en PHP. Funcional, ligero, productivo y bien estructurado, es utilizado por gran número de CMS  (destacando Drupal) y por empresas potentes. Está bajo licencia MIT.
  • Codeigniter: Un veterano, al menos según mi percepción porque fue del primero del que oí hablar. Por lo que se dice tiene menos funcionalidades que Symfony o Zend, pero a su favor juega con tener una mayor flexibilidad y menor peso. Menos productivo pero más adaptable. Su licencia es GNU/GPL.
  • CakePHP: Irrumpió con mucha fuerza hace un par de años, pero parece que al final no ha logrado desbancar a Zend y Symfony del trono, en parte porque se dice que tiene una curva de aprendizaje más pronunciada. Incluye funcionalidades para casi todo y está bajo licencia MIT al igual que Symfony.

Y con estos cuatro no se acaba, hay docenas de frameworks para PHP funcionales como Yii, ZanPHP (de esto no tengo muy claro su estado, porque la web oficial a día de escribir este artículo, aparecía como un dominio caducado, pero en GitHub sigue) o KumbiaPHP. En cualquier caso, la oferta es amplia y variada en ese sentido.

Sesiones en PHP: uso básico

A la hora de guardar los datos de navegación de un usuario de nuestra web el uso de sesiones se torna esencial. Las sesiones son una forma fácil y práctica de almacenar estos datos del usuario (los almacena en una cookie de sesión que gestionará el propio navegador), de forma individual, para trabajar con ellos.

La idea es simple: cuando llamamos a la función session_start() PHP comprueba si existe un ID de sesión, en caso negativo crea una sesión nueva y en caso afirmativo mantiene los datos de la creada. Con la sesión activa podremos utilizar la variable array superglobal $_SESSION para almacenar los datos que queramos relativos a la navegación. Piensa en el carrito de la compra de cualquier tienda on-line, que va almacenando los items que vas comprando hasta que haces el pago, creo que es el mejor ejemplo de cómo funcionan estas variables.

Vamos a ver un ejemplo donde creamos una sesión y almacenamos la hora de la última conexión y de la última acción:

@session_start(); //iniciamos la sessión

if(!isset($_SESSION["first_connection"])){ //comprobamos si existe la variable y si no, inicializamos
  $_SESSION["first_connection"] = time(); //asignamos a la variable la fecha de creación
}else{
  $_SESSION["lastAction"] = time(); //sobreecribimos la fecha de la última acción
}

Un ejemplo tonto, pero básico.

Para destruir una sesión, por ejemplo al pulsar un botón de logout, usaríamos la función @session_destroy(). Y para acceder al id de la misma la función @session_id() nos lo devolverá. Si queremos cargarnos una variable de la sesión sin destruir la sesión basta con usar la función unset(), más o menos como en el ejemplo que va ahora:

//AHORA QUEREMOS DEJAR DE ALMACENAR LA ÚLTIMA ACCIÓN
unset($_SESSION["lastAction"]);

Ni se os curra hacer unset($_SESSION) sin indicar variable para cargároslas todas, esto deshabilitará el registro de las variables del array y os romperá un montón la cabeza.

En fin, como siempre si queréis más ejemplos en la web de PHP podéis explorar sobre el uso de sesiones. Un saludo y que os sea provechoso.

Instalar HexChat en Ubuntu/Mint

Llevo diez días sin escribir nada nuevo… en casa dejé dos artículos de música a medio hacer, pero estoy liadillo con varios proyectos (y muy viciado a un juego del que pronto os hablaré en este blog) y he tenido esto abandonado, aunque por suerte el flujo de visitas sigue constante.

¿Echáis de menos el #IRC? ¿Aquellas primeras troleadas internetianas usando este sistema de chat? ¿Simular ser una tía impresionante para putear a un colega? ¿Discutir a las cinco de la mañana si los Blazers de Adelman habrían sido campeones de haber contado con Petrovic y Sabonis? ¿Comentar la pelea de Shaq vs Barkley? ¿Discutir si es más facha Ted Nugent o Varg Vikerness? En fin, pues con todo todavía hay gente que lo usa (la mayoría salidorros en busca de cibersexo, tampoco nos engañemos). De hecho hoy tuve que usarlo (después de 10 años) por lo que busqué información y acabé llegando a este software.

En fin, si eres usuario de Linux apuesto a que usabas XChat como cliente de #IRC, y si ahora mismo quieres instalarlo estarás viendo que lleva sin actualizaciones desde 2010… Tranquilo, HexChat (que descubrí a través de este artículo brasileño en twitter) es la solución que necesitas. Un cliente IRC libre, desarrollado en Python, con ciertas funcionalidades propias, una interfaz muy limpia y personalizable, permite el uso de scripts tanto de Perl como de Python para la administración, está traducido a varios idiomas y existen binarios tanto para Windows como para Unix/Linux.

El proceso de instalación desde Ubuntu o Mint es fácil, basta tres comandos:

#primero añadimos el repositorio del fabricante:

sudo add-apt-repository ppa:gwendal-lebihan-dev/hexchat-stable -y

#sigue la clásica actualización

sudo apt-get update

#e instalamos

sudo apt-get install hexchat -y

#en el ejemplo de la web brasileña lo hacen todo concatenando los tres comandos:

sudo add-apt-repository ppa:gwendal-lebihan-dev/hexchat-stable -y && sudo apt-get update && sudo apt-get install hexchat -y

En fin, con esto ya tienes tu cliente de IRC nuevecito y actualizado en tu Linux. Podéis visitar la web de los creadores por si tenéis dudas.

El patrón de diseño Singleton (implementado en PHP)

Vamos con la entrada número 400 del blog, y la 200 de informática. Curioso, llegados a este punto de casi dos años bloggeando un tema que no era el principal ha acabado ocupando el 50% del contenido del blog.

En fin, seguimos con los patrones de diseño. El otro día hablaba del patrón Decorator, hoy vamos con el Singleton.

La idea del patrón Singleton, también llamado de instancia única, es restringir la creación de objetos pertenecientes a una clase a sólo uno. Garantiza que sólo hay una instancia y proporciona un único punto de acceso.

La idea es que la clase tenga un constructor privado para que no pueda ser accedido desde fuera de la clase y que aunque haya clases hijas estas no puedan instanciar objetos. También debe tener una propiedad estática privada donde almacenaremos nuestra instancia y un método estático que sea el punto de acceso global a la misma, devolviéndola cuando se lo llama.

Vamos con el ejemplo típico y tópico del objeto de base de datos, que suele ser el uso más común de este tipo de clases. Porque crear varias instancias de acceso a una base de datos en la mayoría de los casos es un malgasto de recursos, lo mejor suele ser tener una sola instancia para realizar las conexiones.

class Database {
//Propiedad estática, inicializada a nulo, donde guardaremos la instancia de la propia clase
    static private $instance = null;
//Definimoms el método constructor como privado
    private function __contruct() {}
     
//Método estatico que sirve como punto de acceso global
    public static function getInstance() {
        if (self::$instance == null) {
//Si no hay instancia creada, lo hace. Si la hay tira p'alante
            self::$instance = new Database();
        }
//Al final devuelve la instancia
        return self::$instance;
    }
	     
 //a continuación ya meterías todas las funciones necesarias para un objeto de base de datos. CRUD, etc...
}

Y ya est… No, sorry man pero no. Con el código así todavía es posible que alguien logre hacer más de una instancia. Y te dirás ¿cómo? Pues porque todavía es posible usar la clonación y la serialización para lograrlo. Cosa mala, pero con los métodos mágicos de PHP5 podemos arreglarnos.

Para evitar la cuestión de la clonación definimos el método mágico __clone() en la clase, para que en lugar de permitir el clonado del objeto nos lance un error y detenga el script:

public function __clone()
{
  trigger_error("No puede clonar una instancia de ". get_class($this) ." class.", E_USER_ERROR );
}

Y vamos con el tema de la serialización y deserialización. Con la función serialize() se puede almacenar una representación apta de una variable (y una instancia de un objeto es, al fina, una variable) mientras que con unserialize() podemos acceder a ella como se si tratara de un clon. De nuevo hay que redefinir un método mágico, en concreto esta vez __wakeup(), que es el método que se invoca al deserializar un objeto. De esa forma se evita que pueda ser accedido. También podría hacerse con __sleep(), que es el que se invoca al serializar, pero veo más práctico evitar la deserialización.

public function __wakeup()
{
  trigger_error("No puede deserializar una instancia de ". get_class($this) ." class.", E_USER_ERROR );
}

En fin, he caído en el ejemplo tópico, pero también me pareció el más claro. Un saludo, disfruta este articulo 400.

El patrón de diseño Decorator (aplicado en PHP)

Iba a poner El patrón de diseño decorator en PHP pero dado que los patrones de diseño son independientes del lenguaje preferí poner un título más matizado. Aunque algunos parezcan empeñados en no usar patrones en PHP (a pesar de que desde PHP5 ya esté orientado a objetos) en un proyecto grande serán útiles.

El patrón Decorator se pensó para permitir herencia múltiple sin que el árbol de clases crezca de forma incontrolada. Permite añadir a un objeto funcionalidades de forma dinámica. Piensa en un juego de rol, piensa en cuando vinculabas una matriz de conjuros a un arma en Runequest… vale, es muy friki, pero lo voy a usar de ejemplo para explicar el patrón.

Imagina que haces un videojuego, inspirado en el antes citado Runequest mismamente. Entonces creas la clase espada, que hace 10 puntos de daño y tiene 20 puntos de armadura. Muy bien, ahora le vinculas un hechizo de armadura extra. Tendrías que crear la clase espada_armadura con 10 puntos más de armadura. Hasta ahí, bien: tienes la clase espada, y la clase hija espada_armadura que hereda de espada.

Ahora imagina que también le vinculas un hechizo que duplica el daño. Tendrías que crear la clase espada_daño, pero también la clase espada_armadura_daño, que sería la clase con ambos hechizos. Para dos funcionalidades has tenido que crear 3 clases hijas. Y ahora supón un tercer hechizo que mejora tu posibilidad de éxito un 100%: espada_éxito, espada_éxito_armadura, espada_éxito_daño, espada_éxito_daño_armadura… y las cuatro clases anteriores. Para tres funcionalidades ya vas en 8 clases, si haces el cálculo progresan en potencias de 2, por lo que para 4 funcionalidades tendrías 16 clases, para 5 32…

El patrón Decorator nos permite evitar esto a base de delegar funciones. Vamos a poner un ejemplo práctico en PHP solucionando el problema anterior, explicado en los comentarios:


//interfaz arma, común a todas las armas
interface iArma{
  public function ataca();
  public function defiende();
}

//clase espada, que implementa la interfaz arma
class espada implements iArma{
  private $armor = 20;
  private $attack = 10;

  public function ataca(){
    return $this->attack;
  }
  public function defiende(){
    return $this->armor;
  }
}

//creamos la clase abstracta Decorator
abstract class espada_decorator implements iArma{
  protected $_espada;
  public function __construct(iArma $Espada){
    $this->_espada = $Espada;
  }
}

//ahora creamos la funcionalidad con más ataque
class extra_attack extends espada_decorator{
  public function ataca(){
    return $this->_espada->ataca()*2;
  }
}

//ahora la funcionalidad de más defensa
class extra_armor extends espada_decorator{
  public function defiende(){
    return $this->_espada->defiende()+10;
  }
}

//ahora podemos crear un objeto espada con la defensa extra
$espada = new extra_armor(new espada());

//y ahora añadimos el ataque extra
$espada = new extra_attack($espada);

Como puedes ver, de esta forma agregamos a nuestro objeto diversas funcionalidades, creando sólo una clase por funcionalidad en lugar del montón al que nos obligaría el ir creando clases para cara posible combinación.

Metapixel: crear mosaicos en linux

Un programa interesante que descubrí la semana pasada es Metapixel. Un software para Linux que nos permite crear mosaicos que generen una imágen a partir de una colección de fotos, más o menos como la imagen del ejemplo:

Gioconda creada con favicons

En los repositorios de Debian y Ubuntu está presente este programa, así que basta con descargarlo del repositorio, y ya puestos creamos una carpeta para guardar allí las miniaturas de las imágenes a usar como fuente:

sudo apt-get install metapixel
mkdir .fuentes

Tras esto toca configurar Metapixel, pasándole la dirección de la carpeta donde guardamos las imágenes para que la asocie con la carpeta de miniaturas:

metapixel-prepare -r carpeta_imagenes/ .fuentes --width=20 --height=15

Cambia lo de carpeta_imagenes por lo que corresponda, los parámetros de tamaño también los puedes cambiar, en este caso le hemos dado 20×15 píxeles. Bueno, ya tenemos todo preparado. Ahora, desde línea de comandos llamamos a Metapixel, le pasamos la imagen de origen (la que tendrá que verse en el mosaico), el nombre del archivo de salida, la biblioteca de miniaturas, el tamaño (un número que representa cuánto mayor será que la imagen original) y el radio de píxeles en los que no puede repetir imágenes. Un ejemplo:

metapixel --metapixel origen.jpg salida.png -l fuentes --scale=30 --distance=20

Lo dicho: origen, destino, librería con las fuentes, tamaño (30 veces mayor que la original) y radio en que no se repite (20 pixeles).

Ahora a trastear y disfrutar con él.

Twig: genera tus plantillas en php

A raíz de los experimentos con Symfony toca continuar y hablar de Twig. ¿Qué es Twig? Se trata de un motor de plantillas libre para el lenguaje PHP. Si has trabajado alguna vez con JSP o con ASP no te resultará raro.

Synfony incluye dentro del framework este motor (también te lo puedes bajar aparte) , que nos ofrece ciertas comodidades respecto a hacer la plantilla en php  pelo. La primera consiste en poder pasar variables las plantillas, con objeto de que estas sean mostradas en pantalla. Las variables pueden tener atributos o elementos en ellas a los cuales puedes acceder también, utilizando el punto (.) o el subíndice ([]) para el caso de un array. También permite realizar iteraciones si la varible es una colección (como un array) o utilizar el condicional if. Con un ejemplo ser verá más claro:

/*PHP tradicional*/
<h1><?php echo strtoupper($title) ?></h1>
<ul>
<?php foreach($collection as $item){ ?>
<li>Nombre:<a href="<?php echo $item->getUrl();?>"> <?php $item->getName();?></a></li>
<?php }  ?>
</ul> 

/*TWIG*/
<h1>{{ title|upper }}</h1>
<ul>
{% for item in collection %}
<li>
Nombre: <a href="{{item.url}}">{{item.nombre}}</a>
</li>
{% endfor %}
</ul>

¿Cómodo? Desde luego, una vez te has acostumbrado. Pero no es lo único que permite Twig, porque su verdadera potencia se encuentra en la herencia entre plantillas. Esto nos permite crear un modelo de plantilla base que contenga todos los elementos comunes del sitio y definir los bloques que las plantillas descendientes pueden sustituir. Imaginemos esta plantilla base:

<!DOCTYPE html>
<html>
    <head>
        {% block head %}
            <link rel="stylesheet" href="stilos.css" />            
        {% endblock %}
    </head>
    <body>
        <div id="content">
          {% block content %}{% endblock %}
        </div>
    </body>
</html>

Muy bien, ahora en las plantillas hija nos basta usar las etiquetas block para insertar el código que será distinto:

{% extends "base.html" %}

{% block head %}
    {{ parent() }}
    <script type="text/javascript" src="jquery.min.191.js"></script>
{% endblock %}

{% block content %}
    <h1>Índice</h1>
    <p>
        Hola mundo!
    </p>
{% endblock %}

Productivo ¿no? Pues no es todo, Twig incluye autoescape de html en las variables para prevenir ataques XSS. En el primer ejemplo ves como al lado de la variable usé upper, eso es un filtro. Existen múltiples filtros que puedes consultar en la documentación oficial de TWIG, al igual que también varias funciones y las etiquetas propias de Twig con varias funcionalidades.