Translate

Mostrando las entradas con la etiqueta metaprogramación. Mostrar todas las entradas
Mostrando las entradas con la etiqueta metaprogramación. Mostrar todas las entradas

lunes, 3 de diciembre de 2012

Utilizando ExpandoMetaClass con Groovy




En el post anterior hablamos de categorías, ahora vamos a utilizar ExpandoMetaClass para agregar un método a una clase:

import org.apache.commons.lang.StringUtils

String.metaClass.capitalize = {
   StringUtils.capitalize(delegate)
}

assert "Groovy" == "groovy".capitalize()

Hemos agregado el método capitalize pero esto no es temporal como cuando usabamos "use". Este método va a quedar en la clase, dado que lo registramos. Con esta técnica se puede agregar métodos nuevos o sobrecargar métodos existentes.

ExpandoMetaClass incluye alguna extension / hooks que se puede utilizar para cambiar la forma en que se comporta una clase o un objeto, podemos hacer lo siguiente:

  • getProperty / setProperty: control de acceso
  • invokeMethod: podemos escribir este método y cada vez que necesite un método se va a llamar la función que necesitamos. Se puede implementar algo como AOP. 
  • methodMissing y propertyMissing: Podemos escribir escribir estos métodos para que se comporten de forma más amable.  


ExpandoMetaClass es una gran mejora sobre lo que ya ha proporcionaba Groovy pero también tiene sus peculiaridades, por ejemplo, la herencia no está activado por defecto (porque va a causar un impacto en el rendimiento)

Dejo link:
http://groovy.codehaus.org/ExpandoMetaClass

Metaprogramación en Groovy, hoy categorías


Groovy es un lenguaje estáticamente tipado por lo tanto no necesitamos definir los tipos; esta característica sumada a la metaprogramación puede ser muy potente.

Todos los objetos en groovy tienen una metaclass responsable de mantener la informacion de las clases. Siempre que llames a un método de un objeto, groovy utiliza un mecanismo de despacho que utiliza esta metaclass. Este mecanismo se puede modificar, groovy ofrece formas de modificarlo, por ejemplo categorías.

Las categorías es un mecanismo muy simple que sigue las siguientes reglas:

  • Los métodos estáticos son candidatos para ser métodos de categorías 
  • No es necesario implementar nuevas clases o interfaces
  • El tipo del primer parámetro, es el tipo del objeto que va a recibir el método.   

Veamos un ejemplo:

class Pouncer {
       static pounces( Integer self ){
                 (0..<self).inject("") { s, n -> s += "boing! " }
        }
}  

use( Pouncer ) {
       assert 3.pounces() == "boing! boing! boing! "
}

La magia sucede con la palabra clave use, donde decimos que la clase integer puede ejecutar pounces. El metodo se puede utilizar solo en scope de use.   Con este mecanismo podemos darle un metodo a una clase por un corto tiempo. Se podria utilizar pafra darle logica a objetos livianos.

viernes, 6 de julio de 2012

Que es la metaprogramación?


La metaprogramación consiste en escribir programas que escriben o manipulan otros programas (o a sí mismos) como datos, o que hacen en tiempo de compilación parte del trabajo que, de otra forma, se haría en tiempo de ejecución. Esto permite al programador ahorrar tiempo en la producción de código. Son programas que escriben programas, me suena a apocalíptico, como la skynet creando robots.

La metaprogramación no es una nueva idea - Nació hace ya más de 40 años, con el lenguaje Lisp, y se popularizó tremendamente en el lenguaje Smalltalk, a principios de los 80.

Como pueden imaginar un lenguaje script o dinamicos, facilita el uso de metaprogramación dado que no tiene que compilar o compilarse, simplemente modifica código y lo va corriendo.


Veamos como crearíamos una clase en Ruby: 



def crea_clase(nombre, clase_padre)
         eval "class #{nombre} < #{clase_padre} ; end"
end

De esta forma podemos hacer lo siguiente:

['Empleado', 'Cliente', 'Otro'].each  do |nombre_de_la_clase|
        crea_clase( nombre_de_la_clase , 'Persona')
end

Y así creamos clases a lo pavote, con 6 lineas de código.

En javascript tenemos el eval que podemos utilizar para correr scripts. Esto esta bueno para hacer ajax de código javascript, por poner ejemplo si el usuario eligió un parametro se muestra el valor del parámetro en un alert o un confirm.


$.get('ajax/test.php', function(dataJavascript) {
    eval (dataJavascript);
});


y en php en la url ajax/test.php tenemos: 


<?php
if (parametro) {
  echo " alert(".parametro."); " ;
}
else {
  echo " confirm(".parametro."); " ;
}
?>

Si podria haber puesto un if en  la función ajax pero era un ejemplo. Existen variados usos para a metaprogramación que nos resuelven problemas de forma elegante.