Monthly Archives: agosto 2009

PHP 5.3

Llego algo tarde, cosas del verano, pero voy a comentar algunas de las mejoras que vienen incluidas en la nueva liberación de PHP, la 5.3.

Para mi, esta versión, además de corregir fallos de la anterior, aporta características que le hacen acercarse aún más a la forma de programación profesional que viene dada con otros lenguajes como Java, C#, C++, Python, Ruby…

Espacios de nombres (namespaces)

Los espacios de nombres, llamados en otros lenguajes: paquetes, módulos, …; con esto, podemos tener organizado nuestro código, no solo en directorios, sino también bien delimitado su espacio de nombres mediante el uso del namespace.

Por ejemplo, si tenemos dos directorios: File y BD; que pertenecen a un programa y cada uno de ellos tiene un archivo para contener la clase Output, en las versiones anteriores de PHP habría que incluir uno u otro, o modificar el nombre para que fuese FileOutput y DBOutput, redundando la ruta con el nombre de la clase.

Ahora, con el uso de namespaces, se puede delimitar con solo agregar una sección de código como esta:

namespace File {
 
    class Output {
        /* ... */
    }
}
 
namespace {
    $f = new File\Output();
}

Static… ahora sí

En las versiones anteriores de PHP, los valores static no eran tratados del todo bien, no permitiéndose algunos usos que parecían lógicos y no produciéndose, sobre todo en la herencia, los resultados que se esperaban.

Ahora, ya se permite el uso de variables para contener el nombre de la clase a la que llamar de forma estática, es decir, ya se permite este uso:

class A {
    public static function say() {
        echo "Hola\n";
    }
}
 
$clase = "A";
$clase::say();

Así mismo, el uso del late state binding, es posible mediante la palabra clave static, de modo que, si se llama a un método estático como static::metodo() en lugar de como self::metodo(), se llama al método de la clase hija que haya sobrecargado al método que se llama. Un ejemplo:

class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        static::who(); // Here comes Late Static Bindings
    }
}
 
class B extends A {
    public static function who() {
         echo __CLASS__;
    }
}
 
B::test();  // output: B

Por último, la función especial __call no se llama cuando no hay un método de clase que no exista, en su lugar se llamará a __callStatic, de modo que se pueda hacer diferencia de cuando se está llamando a un método de objeto y cuando se llama a un método de clase.

Más de Late State Binding

Hasta ahora, cuando se quería hacer una clase abstracta que llamase a funciones de sus clases hijas, que aún no han sido declaradas, éstas debían ser abstractas. Pero si la clase no era abstracta y el método a llamar no constaba como abstracto, la llamada no se realizaba a esa función, sino a la del padre.

El sistema de late state binding, asegura que la llamada a métodos se hará siempre de abajo a arriba, es decir, si existe un método en la clase hija que se instanció, aunque el método en ejecución sea el del padre, el método que se llama es el de la clase hija. Más o menos lo que se vió con los métodos estáticos, pero esta vez con métodos.

Funciones anónimas

El uso de funciones anónimas (closures o lambda) es una técnica de programación que permite completar código escrito, mediante el desarrollo parcial de algún algoritmo. Imagina que quieres hacer un código en el que tengas que hacer algo, un paso inicial, un paso intermedio y, en cada iteración una ejecución específica, para terminar con un último paso tras esa iteración.

El código concreto dentro de la iteración puede variar… y de hecho variará en cada implementación, pero el resto no, el resto se mantiene de forma fija. Pues, se puede implementar el esqueleto del programa, y aceptar como parámetro de la función que se haga, una variable que contenga el código a ejecutar. La función que completaría nuestro código se puede hacer así:

$code = function ($dato1, $dato2) {
    echo $dato1 . "--" $dato2 . "\n";
};
 
algoritmo($code);
 
function algoritmo( $func ) {
    for ($i=0; $i<100; $i++) {
        $func($i, $i*$i);
    }
}

También se pueden emplear funciones como array_walk, preg_replace_callback, uasort, etc.

Esto permite realizar códigos como los que se realizan en Ruby o en los lenguajes funcionales y declarativos.

Recolector de Basura de Referencias Circulares opcional

Se deja al programador la decisión de si quiere activar el recolector de referencias circulares del garbage collector, o no. Por defecto viene activado y actúa de la siguiente forma, con este código:

class A {
    function __construct () {
        $this->b = new B($this);
    }
}
 
class B {
    function __construct ($parent = NULL) {
        $this->parent = $parent;
    }
}
 
for ($i = 0 ; $i < 1000000 ; $i++) {
    $a = new A();
    unset($a);
}
 
echo number_format(memory_get_usage());

Si se ejecuta desde consola, con una versión de PHP anterior a la 5.3, se verá en pantalla un error fatal, de que el límite de memoria se ha superado.

Esto es debido a que la liberación de memoria, cuando se va a proceder a liberar la clase B, ve que tiene una referencia a A, que ya va a ser liberada y crea un ciclo, con lo que, para evitarlo, no libera B. En las versiones de PHP 5.3 en adelante, se detecta este ciclo como tal y se liberan ambas.

También existe la posibilidad de desactivar este comportamiento o ver si está activo, con las funciones gc_enable, gc_enabled y gc_disable.

Nowdoc y Heredoc

Hasta ahora, los bloques de tipo heredoc eran los únicos que permitían escribir de forma libre un texto para después usarlo como variable. Ahora también disponemos de los nowdoc, que son iguales, salvo que no se hace parseo de variables. Un ejemplo:

$hola = "Hi, ";
 
$hd = < <<END
texto $hola
END;
 
$nd = <<<'END'
texto $hola
END;
 
echo $hd; // output: texto Hi,
echo $nd; // output: texto $hola

Constantes

Ahora, la palabra clave const puede ser empleada fuera del alcance de una clase, con lo que, en lugar de usar define se puede emplear esta forma:

// antes
// define("CONSTANTE", "Hola mundo!");
 
// ahora
const CONSTANTE = "Hola mundo!";

Operador Ternario simplificado

El operador ternario (expr1)?(expr2):(expr3) ahora permite dejar vacío el espacio correspondiente a (expr2) de modo que si (expr1) es verdadero, se retorna (expr1) y si es falso, se retorna (expr3).

Nuevos Módulos

PHPar

Al igual que JAR, PHPar sirve para empaquetar los PHP en un solo fichero, con lo que se mejora el despliegue de las aplicaciones, la organización del código, etc.

Intl

Mejores funciones de internacionalización para PHP. Hasta ahora, en PHP el único soporte de internacionalización que había disponible era gettext, ahora, con el uso de Intl y sus clases, se facilita internacionalizar una aplicación web, ya que tiene soporte para numeración, fecha, etc.

FileInfo

Da información sobre ficheros, usando la cabecera magic del propio fichero, intenta localizar de forma heurística su tipo, pudiendo retornarlo en formato MIME.

Etiquetas de Salto

Bueno, como en todo, hay avances y retrocesos, esto de proporcionar a PHP un elemento de código spaguetti como es el goto, no hace sino potenciar los malos usos, por lo que yo descartaría su uso.

Migración

Como cualquier liberación de lenguaje, PHP viene con mejoras, agregados y, además, cambios que implican que códigos anteriores puedan dejar de funciona, con lo que es aconsejable leerse bien la guía de migración, para ver los cambios que se introducen, lo que llega a ser deprecated, etc.

Conclusiones

Con esta liberación, PHP da varios matices que le hacen acercarse más a lenguajes como C++ y Java, agregando cosas como PHPar y los namespaces, así como mejorando su implementación de POO.

Considero que el cambiar a esta versión y desarrollar con las nuevas implementaciones hará que los códigos desarrollados sean más claros y, sobre todo, más organizados, por lo que es una buena baza para realizar el cambio.

Además, viendo la guía de migración, se deja entrever que los cambios de la versión anterior, 5.2.x, a esta nueva rama, son mínimos, con lo que, si se ha desarrollado código acorde a la versión anterior, realizar los cambios para adecuarse a esta versión, no es nada complicado.

Manifiesto Ágil

El manifiesto ágil fue fruto de una reunión que se mantuvo en Salt Lake City en marzo de 2001. Diecisiete críticos de los modelos de mejora del desarrollo del software basado en procesos, convocados por Kent Beck, padre del Xtreme Programming, escribieron el siguiente manifiesto:

Estamos poniendo al descubierto mejores métodos para desarrollar software, haciéndolo y ayudando a otros a que lo hagan. Con este trabajo hemos llegado a valorar:

  • A los individuos y su interacción por encima de los procesos y las herramientas.
  • El software que funciona por encima de la documentación exhaustiva.
  • La colaboración con el cliente por encima de la negociación contractual.
  • La respuesta al cambio por encima del seguimiento de un plan.

Aunque hay valor en los elementos de la derecha, valoramos más los de la izquierda.

Entre estas diecisiete personas estaban: Kent Beck, uno de los tres creadores del Xtreme Programming; Alistair Cockburn, padre de los Crystal Methods; Martin Fowler, gran defensor de la Refactorización; Ward Cunningham, estudioso de los patrones y antipatrones de diseño del software y otro de los creadores de Xtreme Programming; Ron Jeffries, otro de los creadores del Xtreme Programming; Jeff Sutherland, gran promotor de Scrum.

Individuos y su Interacción sobre Procesos y Herramientas

No hay que malentender estas palabras tomándolas en su sentido más radical. La expresión de esta frase se refiere que se valora más la comunicación humana, las reuniones y lo que una persona pueda transmitir a otra, que las herramientas.

Así mismo, se considera más importante la valía de la persona, del programador y del diseñador, que los procesos establecidos en sí.

Software que funciona sobre Documentación exhaustiva

Es lógico que, si tengo un software que no funciona como quiero, da igual lo grande que sea la documentación. Es más útil un programa intuitivo, que hace única y exclusivamente lo necesario y tiene una calidad interna alta (código limpio, claro y con comentario concisos) que un software enrevesado que necesita un manual de no menos de 100 páginas para poder entenderlo.

Colaboración con Cliente sobre Negociación Contractual

La firma de un contrato ata a ambas partes a realizar un cierto desarrollo en un determinado tiempo con un gasto prefijado, solo que estos valores son solo estimados.

El contrato debe de existir, pero hay que colaborar con el cliente en realizarlo de forma más flexible, es decir, que los desarrollos sean de períodos cortos y vayan dando valor al cliente, de modo que, con esas cortas entregas, el cliente pueda decidir el curso a seguir entre iteraciones con sus peticiones y los desarrolladores realizar solo el esfuerzo necesario.

Respuesta al cambio sobre Seguimiento de un plan

Como comentaba, salvo para administraciones públicas, los desarrollos que se realizan a vista de un año o más, no suelen aportar valor al cliente hasta terminado ese período de espera. Una empresa que necesita un software, normalmente no puede dar unos requisitos fijos que, a lo largo de los siguientes meses, no cambien debido a un cambio externo o una necesidad de la propia empresa.

Por este motivo, la respuesta al cambio es vital y muy necesaria y, como indicaba el punto anterior, el hecho de poder hacer iteraciones y dar valor al cliente cada poco tiempo es lo que se persigue con el desarrollo ágil.

Conclusión

Esto se produjo en marzo de 2001, desde entonces ninguno de los diecisiete, más otros igualmente grandes, como Mary Poppendieck o Mike Cohn, no han parado de aportar bibliografía sobre el tema y métodos o matizaciones de los métodos ya existentes.

En este sentido, se puede decir que el desarrollo del software es un terreno vivo, donde no paran de descubrirse y crearse métodos y técnicas, para poder abarcar de una forma más exacta el desarrollo de un proyecto de software.

Lenguajes Funcionales para el Desarrollo Web

La web concurrente, a prueba de fallos y distribuida ya va siendo más fácil de desarrollar gracias a dos iniciativas paralelas. Una de ellas es Erlyweb, el entorno desarrollado por Yariv Sadan que permite realizar de forma fácil sitios web en lenguaje Erlang. La otra es Lift, un framework de desarrollo web para otro lenguaje funcional: Scala.

¿Lenguaje funcional para la web?

Muchos se harán esta misma pregunta, si de siempre, los lenguajes imperativos han sido empleados para el desarrollo de aplicaciones web (Java, PHP, Ruby, Perl, C#, …), ¿por qué emplear un lenguaje funcional como Scala o Erlang?

Las ventajas son las siguientes:

  • El lenguaje funcional obliga a pensar lo que se programa, realmente, en este tipo de lenguajes también es posible cometer errores y hacer barbaridades, pero en menor medida. Por regla general, lo que se programa en un lenguaje funcional, suele ser meditado, pensado y puede ser probado de mejor forma.
  • Obliga a organizar el código, ya que todo gira en torno a crear funciones que se llamen unas a otras y a sí mismas, así como tener el código separado en módulos o bloques funcionales. Por ejemplo, en Erlang, para emplear OTP (gen_server, gen_event, gen_fsm…) se debe de crear un módulo para cada uno de ellos, con lo que todo queda bien organizado.
  • El código resultante es más corto y más legible, ya que el código funcional no reutiliza variables, se basa en listas y tiene menos estructuras de control que los lenguajes imperativos, sí, resulta más fácil de comprender el lenguaje en sí y el código, una vez se va leyendo.
  • Tienen ventajas cuando se habla de concurrencia, tiempo real y tolerancia a fallos. Obviamente, si no se permite la reasignación, no se permite cambiar el valor de un dato ya asignado y, por tanto, no hay cabida para la memoria compartida, con lo que la concurrencia se simplifica de forma sorprendente. Por otro lado, estos lenguajes han sido pensados y desarrollados para distribuirse en varios nodos y/o equipos, pudiendo migrar sus procesos entre nodos y sustituir al nodo principal en caso de no estar operativo.

En lo que respecta al lenguaje en sí, se ve claro y, hasta muchos pensarán: ¡mierda!, he perdido el tiempo aprendiendo y usando PHP (o Perl, o Ruby, o Java…); pero no hay que ser tan radical, estos lenguajes son muy útiles y ofrecen muchas ventajas a los lenguajes tradicionales web y, gracias a los frameworks desarrollados, las mejoras son increíbles.

Si tan bueno es… ¿por qué no se usa?

Seamos sinceros, la razón de uso de un sistema u otro se basa, íntegramente, en la popularidad, la costumbre y los malos usos. Cuando en tu entorno hasta 3 personas dicen que PHP es bueno para la web, ya sabes que es lo que hay que aprender si quieres hacer web, pero eso no debería de ser lo único a calibrar, y sobre todo si el conocimiento que se adquiera de PHP se usará para el desarrollo profesional de aplicaciones.

Erlang lleva muchos años usándose en el terreno de las telecomunicaciones y Yariv, el creador del framework Erlyweb, integra servicios desarrollados en Erlang para Facebook, con lo que, los grandes de Internet, ya se han dado cuenta de que hay que dar un paso hacia adelante. Por otro lado, Scala es usado en otros sitios como Twitter.

Ahora de verdad, ¿por qué usarlos?

El desarrollo de entornos web conlleva el uso de varias tecnologías que se usen de forma coordinada y limpia. Desarrollar un software en cualquier lenguaje mezclado con SQL y código en HTML con CSS incrustado y código JavaScript repartido por todos lados hace que el código sea difuso. Difícil de entender.

Sin embargo, con C# y Java se comenzaron a emplear soluciones que han ido trascendiendo a lenguajes de scriptting como Ruby, Python o PHP, en los que ya no se dejan ver consultas SQL, sino el uso de objetos y funciones, el código de presentación queda almacenado por separado con etiquetas especiales, helpers y otros añadidos, los códigos HTML validados, los CSS en sus respectivos ficheros aparte y agregados desde la sección pertinente e incluso el uso del JavaScript no intrusivo.

Llegados a este punto, nos encontramos con que, desarrollar web es, tan solo, desarrollar. Realizar el programa en un solo lenguaje y de forma fácil. Pero aún así, volvemos a encontrar lo que ya había tiempo atrás, nuestro lenguaje imperativo puede contener fallos lógicos y, si es un lenguaje de scriptting muy permisivo, algunos de esos fallos son difíciles de perseguir.

El uso de un framework como lift o erlyweb facilita el seguimiento de fallos, desarrollar en erlang y scala facilita el desarrollo propio de la aplicación y agrega factores determinantes de crecimiento de la misma, así como estabilidad, ¿qué más se puede pedir?