viernes, 31 de julio de 2015

Construir un módulo Joose JS

Module(name,function)

La función global Module(name,function) hace que crear un namespace para las clases, roles y prototipos sea muy fácil. El módulo automáticamente crea el namespace llamado "name". Las clases que son creadas dentro de la función "function" serán puestas automáticamente dentro del namespace del módulo. Esto reduce el riesgo de conflictos de nombres. Un módulo proporciona una buena forma de estructurar y organizar el código que compone un proyecto (múltiples módulos) o una librería (normalmente un único módulo).

Module("com.test.module", function (m) {
    Class("Test", {
        methods: { world: function () { return "hello" } }
    });
    Class("Test2", {
        methods: { world: function () { return "hello" } }
    })
})

En el ejemplo la clase Test será globalmente conocida bajo el nombre "com.test.module.Test" y así se reduce el riesgo de conflictos de nombres.

jueves, 30 de julio de 2015

Construir una clase Joose JS

La función global Class(name, properties) crea una clase con el nombre "name". La clase es inicializada usando sus propiedades "properties" de esta manera:
  • isa: Indica de qué clase hereda, o sea, su superclase
  • does: Aplica roles a la clase
  • has: Crea atributos para la clase
  • methods: Crea los métodos de instancia
  • classMethods: Crea los métodos de clase
Existen también modificadores de métodos: before, after, around, override, augment

isa

Class("Avion", {
 isa: Transporte
})

En el ejemplo Avion heredará todos los métodos de la clase Transporte. No hay Herencia Múltiple.

does

Class("Pintura", {
 does: Coloreable
})

Aplica roles, a veces llamado traits (algo similiar a mixins), a la clase. Para aplicar múltiples roles se le pasa un array de roles.

has

Class("Puerta",{
 has: {
  color: {
   is: "rw",
   init: "blanca"
  },
  material: {
   is: "ro",
   init: "madera"
  }
 }
}

En el ejemplo la clase Puerta tiene dos atributos: color y material. El atributo "color" es de lectura/escritura y es inicializado a "blanca". El atributo "material" es de sólo lectura y es inicializado a "madera". Joose genera los métodos de acceso a los atributos automáticamente, en este caso se llamarían: getColor(), setColor(), getMaterial(). No hay un método setMaterial() porque fue declarado de sólo lectura.

methods

methods: {
 clear: function(){
  this.setX(0);
  this.setY(0);
 },
 stringify: function(){
  return "" + this.getX() + "," + this.getY()
 }
}

En el ejemplo agregamos dos métodos a la clase, los métodos clear() y stringify(). El primero para limpiar los atributos de la clase y el segundo para devolver un string que representa los valores de sus atributos.

classMethods

classMethods: {
 makeNew: function(){
  return new Punto3D()
 }
}

Funciona como "methods" pero para generar métodos de clase en vez de métodos de instancia. Ahora podemos crear un Punto3D llamando a Punto3D.makeNew()

Modificadores de métodos


Los métodos declarados como "before" son llamados antes del método que sobreescriben. El valor de retorno es descartado.
before: {
 clear: function(){ alert("Antes: " + this.stringify()) }
}

Los métodos declarados como "after" son llamados después del método que sobreescriben. El valor de retorno es descartado.
after: {
 clear: function(){ alert("Después: " + this.stringify()) }
}

Métodos especiales


Los objetos Joose devuelven el string "a ClassName" cuando se llama al método stringify(), siendo ClassName el nombre de la clase a la que pertenece el objeto. Éste método se puede sobreescribir. Algunos engines Js utilizan el método toString(), por eso no se modifica directamente toString(), Joose utiliza stringify().
Existe el método initialize() que Joose automáticamente utiliza para inicializar una instancia como esta: var point = new Point({x:10, y: 10})
Se lo puede sobreescribir para cambiar ese comportamiento. O podría ser útil definir un modificador "after" para el método initialize().

miércoles, 29 de julio de 2015

Clase Punto3D en Javascript usando Joose

Javascript


En Javascript vamos a implementar una clase Punto3D que hereda de la clase Punto implementada antes aquí.
// Implementamos una función para herencia
function inherit(superClass, subClass) {
    for(var i in superClass.prototype) {
        subClass.prototype[i] = superClass.prototype[i]
    }
}
Test.StandardPoint3D = function (x, y, z) {
    this.x = x || 0
    this.y = y || 0
    this.z = z || 0
}
// Hacemos que Test.Standard sea la super clase de Test.StandardPoint3D
inherit(Test.StandardPoint, Test.StandardPoint3D)
// No podemos asignar un nuevo prototipo porque ya tenemos uno de la super clase
Test.StandardPoint3D.prototype.getZ = function () {
    return this.z
}
Test.StandardPoint3D.prototype.setZ = function (z) {
    this.z = z;
}
var superMethod = Test.StandardPoint3D.prototype.clear;
Test.StandardPoint3D.prototype.clear = function () {
    superMethod.apply(this);
    this.z = 0;
}


Joose


Ahora reimplementamos la clase Punto3D usando la librería Joose y vemos que el nuevo código es más compacto y legible porque se ocupa de lo que nos importa.
Module("Test", function (m) {
    Class("Point3D", {
        isa: m.Point,
        has: {
            z: {
                is: "rw",
                init: 0
            }
        },
        after: {
            clear: function () {
                this.setZ(0)
            }
        }
    })
})

domingo, 26 de julio de 2015

Ejemplo de código Joose

Descargamos la libreria joose.js de https://code.google.com/p/joose-js/downloads/list y creamos este pequeño ejemplo llamado runpoint.html:


<!DOCTYPE html>
<html>
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" >
  <script type="text/javascript" src="./joose.js"></script>
  <title>Joose Point</title>

  <script type="text/javascript">
  Class("Punto", {
   has: {
    x: {is: "rw"},
    y: {is: "rw"}
   },
   methods: {
    clear: function () {
     this.setX(0);
     this.setY(0);
    }
   }
  });

  Class("Punto3D", {
   isa: Punto,
   has: {
    z: {is: "rw"}
   },
   after: {
    clear: function () {
     this.setZ(0);
    }
   }
  });
  </script>

 </head>
 <body>

  <script type="text/javascript">
  var point = new Punto3D();
  point.setX(10);
  point.setY(30);
  var y = point.getY();
  point.z = 1;
  console.log("Un punto: ");
  console.log(point);
  console.log("var y: " + y);
  point.clear();
  console.log("Coordenada z luego de clear: " + point.getZ());
  var point2 = new Punto3D({ x: 10, y: 20});
  console.log("Coordenada y de point2: " + point2.y);
  </script>

 </body>
</html>

La salida en la consola del navegador es algo como esto:



runpoint.html:41 Un punto:
runpoint.html:42 f {x: 10, y: 30, z: 1}
runpoint.html:43 var y: 30
runpoint.html:45 Coordenada z luego de clear: 0
runpoint.html:47 Coordenada y de point2: 20

Clase Punto en Javascript usando Joose

Javascript


En Javascript vamos a implementar una clase Punto con los atributos x e y usando el namespace Test.
if(Test == null) {
    Test = {};
}
Test.StandardPoint = function (x, y) {
    this.x = x || 0
    this.y = y || 0
}
Test.StandardPoint.prototype = {
    getX: function () {
        return this.x
    },
    setX: function (x) {
        this.x = x
    },
    getY: function () {
        return this.y
    },
    setY: function (y) {
        this.y = y;
    },
    clear: function () {
        this.setX(0)
        this.setY(0)
    }
}

Joose


Ahora reimplementamos la clase Punto usando la librería Joose y vemos que el nuevo código es más corto y fácil de leer.
Module("Test", function (m) {
    Class("Point", {
        has: {
            x: {
                is:   "rw",
                init: 0
            },
            y: {
                is:   "rw",
                init: 0
            }
        },
        methods: {
            clear: function () {
                this.setX(0);
                this.setY(0);
            }
        }
    })
})

jueves, 23 de julio de 2015

Pequeña introducción a POE

POE es un framework escrito en Perl. POE permite escribir programas que manejan entradas desde múltiples fuentes asíncronas. Éstas son grandes palabras, pero sólo significa que obtendrás la información cuando esté disponible, y no tendrás que preocuparte por quedarte esperando.

La cooperación se logra creando un conjunto de estados, los cuales son invocados por eventos. Los eventos son generados por los motores de entradas (llamados aquí Wheels), por los timers o por otros estados.
En el corazón de POE se encuentra el POE kernel. Mantiene una cola de eventos programados y utiliza la funcionalidad select o poll del Sistema Operativo para ver la actividad de los sockets o manejadores de archivos que te interesan. Cuando sea el tiempo de disparar un evento, o hay datos disponibles, el manejador del estado asociado es invocado. Otros event loops están también disponibles, haciendo posible tener programas POE que tengan interfaces de usuario Tk o curses, por ejemplo.

Ejemplo: cómo hacer una entrada de datos con timeout

En este tutorial veremos cómo ponerle un timeout a la STDIN. Veremos que es fácil escribir aplicaciones interactivas en POE con edición en la línea de comandos y con historial.
El primer paso en cualquier programa POE es usar el módulo POE. Como los programas POE a menudo necesitan usar varios módulos del namespace POE::, tú puedes hacer

use POE qw/Wheel::ReadLine Component::Client::HTTP::SSL/;

como un atajo para

use POE;
use POE::Wheel::ReadLine;
use POE::Component::Client::HTTP::SSL;

En nuestro ejemplo sólo necesitamos POE::Wheel::ReadLine, el cual maneja nuestros requerimientos de entrada.
Cada programa consiste en una o más sesiones POE, las cuales mantienen un conjunto de estados.

#!/usr/bin/perl -w
use strict;

# Use POE!
use POE qw/Wheel::ReadLine/;

# Need to do this on Cygwin
#$/="\n\r";

# flush STDOUT automatically
$|++;


  POE::Session->create(
    inline_states =>
      { _start    => \&handler_start,
        gotLine   => \&handler_gotLine,
        prompt    => \&handler_prompt,
        timeout   => \&handler_timeout,
        #_stop     => \&handler_stop,
      }
  );

En el constructor de la sesión especificamos un hash de nombres de estados, y los manejadores asociados a esos estados. Las subrutinas pueden tener nombre, como aquí, o ser referencias a subrutinas anónimas.
Los estados _start y _stop son especiales, ellos son invocados por el kernel cuando la sesión es creada, o justo antes de ser destruída.
En este caso no necesitamos hacer nada especial para manejar el _stop, así que este estado es comentado y su manejador no es implementado.
El manejador del _start será invocado antes que POE::Session->create() retorne.
El próximo paso es hacer andar el kernel, y salir del programa una vez hecho esto.

$poe_kernel->run();
exit;

$poe_kernel es exportado por POE automáticamente.

Manejadores

De acuerdo, no hemos definido ningún manejador todavía, así que nuestro programa aún no compila, ni siquiera corre.
Cada manejador recibirá un largo número de argumentos en @_. Los más interesantes son el heap, el kernel y el session asociados con el estado.
El heap es solo un escalar, casi siempre una referencia a hash.
Éstos valores pueden ser accedidos usando un array slice sobre @_ para inicializar variables, o explícitamente referenciadas por $_[HEAP], $_[KERNEL], $_[SESSION]. POE exporta HEAP, KERNEL, SESSION y otras constantes varias en forma automática.

El primer manejador que veremos es nuestro manejador de start:

sub handler_start {
  my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION];

  # POE::Wheel::ReadLine gets you terminal input with command line
  # history.  whenever a line is input, the 'gotLine' event
  # will run
  $heap->{wheel} = POE::Wheel::ReadLine->new
      (
        InputEvent => 'gotLine',
    );

  # ask for the prompt event to get run next
  $kernel->yield('prompt');
}

Wheels

Los módulos POE::Wheel son los que manejan el pegamento molesto de nuestros generadores externos de eventos, tales como sockets o manejadores de archivo, hacia los estados POE.
POE::Wheel::ReadLine es el que invoca estados cuando los datos son entrados por la consola. También maneja la edición y el historial en la línea de comandos, con un poco de ayuda de nosotros.
Note que salvamos el wheel en nuestro hash %{$heap}. De otro modo el wheel sería inmediatamente destruído, desde que no habría referencias hacia él. Usaremos este truco de nuevo más tarde, cuando sea tiempo de salir. Por ahora asociamos el InputEvent del wheel con el estado 'gotLine' (manejado por la subrutina _gotLine). Entonces usamos el "yield" para pedirle al kernel que ejecute el estado prompt lo antes posible.

sub handler_prompt {
  my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION];

  print "You have 10 seconds to enter something, or I'll quit!$/";
  $heap->{wheel}->get('Type fast: ');

  # this will make the timeout event fire in 10 seconds
  $kernel->delay('timeout',10);
}

En este manejador usamos el método get en nuestro wheel para pedirle una entrada al usuario y programamos un timeout de 10 segundos.
Aún si no es la primera vez que el manejador es invocado, la llamada a delay() elimina el evento anterior y programa uno nuevo de 10 segundos.
A partir de aquí las cosas están en manos del kernel. Si el usuario no hace nada en 10 segundos (más o menos, los tiempos de espera son aproximados) el estado de timeout será activado.

sub handler_timeout {
  my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION];

  # taunt (or inform) the user
  print "You took too long, game over$/";

  # setting this to undef will make our Wheel get shutdown
  # with no wheel, and no pending delay event, the kernel
  # queue is empty resulting in shutdown
  $heap->{wheel}=undef;
}

Cuando el atributo wheel es puesto undef en la subrutina handler_timeout, el wheel es destruído, y dado que no hay eventos pendientes ni otras fuentes de eventos, el kernel termina.
Si el usuario entra algo por consola o presiona Ctrl-C, el manejador gotLine es llamado.


sub handler_gotLine {
  my ($kernel, $heap, $session, $arg, $exception) = 
            @_[KERNEL, HEAP, SESSION, ARG0, ARG1];

  if(defined $arg) {
    $heap->{wheel}->addhistory($arg);
    print "Very good, you entered '$arg'.  You get another 10 seconds.$/";
  }
  else {
    print "Got input exception '$exception'.  Exiting...$/";

    # setting this to undef will make our Wheel get shutdown
    $heap->{wheel}=undef;
    # setting a delay without a timeout number clears the event
    $kernel->delay('timeout');

    return;
  }

  # run the prompt event again to reset timeout and print
  # new prompt
  $kernel->yield('prompt');
}

Una cosa interesante aquí es que leemos ARG0 y ARG1 de @_. POE pasa argumentos en @_ en el rango ARG0 hasta $#_. En el caso de un InputHandler para este wheel, ARG0 será el texto de la entrada, y si es undef, ARG1 será el código de excepción.
Después de manejar la entrada, este manejador lleva de nuevo al manejador 'prompt', el cual reprograma el timeout y pide datos al usuario de nuevo.



miércoles, 22 de julio de 2015

Qué es Joose

Qué es el framework Joose

Fuente del Joose

El código fuente de Joose es hosteado en GitHub

Joose

Es una librería open-source de JavaScript que soporta clases, herencia, mixins, traits y programación orientada a aspectos. Su sistema de objetos es multiparadigma, soporta el estilo de programación basado en clases y en prototipos. Joose se especializa en dotar al lenguaje JavaScript de técnicas de programación exitosas, por eso se lo usa a menudo con otros frameworks orientados al DOM/Ajax, como jQuery, YUI, Dojo, Prototype, Mootools y PureMVC.

Ejemplos de clases con Joose

A continuación implementamos dos clases con Joose: la clase Punto y la clase Punto3D
Class("Punto", {
    has: {
        x: {is: "rw"},
        y: {is: "rw"}
    },
    methods: {
        clear: function () {
            this.setX(0);
            this.setY(0);
        }
    }
});

Class("Punto3D", {
    isa: Punto,
    has: {
        z: {is: "rw"}
    },
    after: {
        clear: function () {
            this.setZ(0);
        }
    }
});
Punto3D es una subclase de Punto. Tiene un atributo más y un código adicional que corre antes del método clear() de su superclase. El valor "rw" significa que el atributo del objeto se de lectura y escritura, es decir que automáticamente se generan los métodos de acceso get() y set().

Qué es POE Perl

El POE o Perl Object Environment es una librería de módulos escrita en Perl por Rocco Caputo y otros. Originalmente fue desarrollada como el núcleo de un entorno de ejecución y servidor de objetos persistentes. Evolucionó en un framework de propósito general para multitarea y networking, abarcando y proveyendo una interfaz consistente para otros bucles de eventos tales como Event y los toolkits Tk y Gtk.

Capas de abstracción: Arquitectura POE

POE puede ser pensado como un pequeño sistema operativo modular. Uno o más programas o instancias POE pueden correr juntas en forma concurrente y son generalmente muy adecuadas para multitarea colaborativa. El paquete POE consiste en abstracciones y namespaces que guian el futuro desarrollo de POE en una convención abierta-cerrada al estilo CPAN.

La capa de evento

La arquitectura informal consiste en un conjunto de capas con un kernel de fondo. Este pequeño kernel representa la capa de eventos, los cuales operan como el loop principal de cada instancia POE que está corriendo. La primera llamada es al "despachador de eventos" - POE::Kernel.

La capa I/O

El próximo requerimiento del Kernel es para los manejadores de Input-Output que existen en una sola capa de I/O llamada Wheels. Wheels inicia acciones, maneja los resultados de eventos de bajo nivel y produce eventos de alto nivel para las sesiones que los usan. Wheels es construido como un conjunto uniforme de abstracciones - POE::Wheel, que se sitúa por encima del Kernel. Hay siete Wheels en la distribución base de POE que son altamente especializados y bien definidos.

La capa de archivos

Los manejadores que realmente trabajan leyendo y escribiendo archivos. Se construyen de acuerdo a definiciones menos abstractas contenidas en el módulo POE::Driver.

Componentes POE

Varios paquetes más grandes han sido escritos en POE de acuerdo a la documentación POE::Component. Estos módulos son manejadores de eventos, la mayoría de los cuales son pequeños demonios que proveen servicios a paquetes más grandes a los que pertenecen. Algunos facilitan comunicaciones de alto nivel entre módulos, especialmente a aplicaciones que necesitan mantener independencia del resto de la distribución Perl.
En general los componentes POE son procedimientos de alto nivel que realizan grandes tareas. Por ejemplo:
  • Component::Server::TCP - un servlet TCP de propósito especial
  • Component::Client::TCP - un cliente TCP POE-aware
  • POE::Component::IRC - un cliente IRC con casi todas sus funcionalidades
  • POE::Component::Server::IRC - un servidor IRC bajo desarrollo
  • POE::Component::UserBase - un servlet para persistencia de datos y autenticación de usuarios
Los componentes POE tienden a ser librerías altamente reusables que manejan tareas tediosas, liberando a los programadores para que se enfoquen en hacer cosas más interesantes. 

martes, 21 de julio de 2015

Testear con Perl una expresión regular

En la vida de todo programador Perl hay un momento especial en el que hay que escribir una expresión regular. Entonces nos encontramos con que nuestro patrón matchea con más o menos de lo esperado. O nada en realidad.
Este script es util para testear nuestros patrones de ExpReg con algún string y ver si matchea y dónde matchea:

    #!/usr/bin/perl

    # lee una linea de entrada a la vez
    while (<>) {
      chomp;
      if (/YOUR_PATTERN_GOES_HERE/) {
        # codigo misterios! ver explicacion
        print "Matched: |$`<$&>$'|\n"; 
      } else {
        print "No match.\n";
      }
    }

Este script es un test para que lo usen los programadores, no los usuarios finales. Por eso no tienen ningún prompt ni información de cómo se usa. Toma cualquier número de líneas como entrada y chequea cada una contra el patrón que colocas en lugar de "YOUR_PATTERN_GOES_HERE". Para cada línea que matchea se ejecuta el "codigo misterioso". Lo que hace es colocar entre paréntesis angulares el string que coincide con el patrón. Por ejemplo si el patrón es /match/ y la línea de entrada es antesmatchdespues, la salida dirá "antes<match>despues". De esta forma se hace más visible con qué parte de la cadena matchea el patrón. Prueba y verás!