Interceptores (Continuación)

Siguiendo con la idea de los interceptores y esta pseudo AOP, finalmente pude subir el código a GitHub.

Claramente faltan algunas cosas (Minimizar por ejemplo), pero espero ir evolucionándolo.

En cualquier caso, pueden verlo aquí: https://github.com/MatiasIac/ToolPack

Como mostraba en el post anterior, algunos puntos a destacar eran la detección de dónde inyectar el código y cómo reconocerlo desde el mismo JavaScript sin tener que usar un meta lenguaje o algo que corra por fuera del mismo JavaScript.

s.prototype.sum = function (a, b, result, __interceptor) {
   console.log('Sum function called');
   console.log(a + b);
};

En este caso, cualquier variable que sea colocada en la firma de una función y que además inicie con __ sería tomada como el nombre del interceptor a ser ejecutado cuando esta función se llamase.

En la definición de los interceptores, entonces, tendríamos lo siguiente:

Interceptor.define('__interceptor')...

Definiendo el interceptor mediante su nombre y pudiendo agregar diferentes funciones anónimas, en cascada, que se ejecuten generando un resultado.

.having(function() {
   console.log('interceptor called');
   console.log(this);
   return "hola";
}, { context: { ok: true }, injectResult: true })

Si bien en este ejemplo no se manejan las variables que se pasaron originalmente a la función que intentábamos llamar, las mismas pueden ser declaradas en la firma de la función anónima o tomarlas desde arguments.

Solo como para darle algo de sabor a todo esto, opté por dar la posibilidad de configurar cada interceptor mediante un objeto de configuración. En este caso sería posible pasarle un contexto particular al interceptor, el que pudiera ser accedido mediante this, y también permiter retornar sus resultados e inyectarlos dentro de la función que finalmente es llamda.

Volviendo al código inicial, la variable result contendrá todos estos valores.

s.prototype.sum = function(a, b, result, __interceptor)

Seguramente dedique otro post a describir internamente el interceptor… pero eso vendrá luego 🙂

Anuncios

Interceptores y JavaScript

Primero que nada decir que estoy armando este post desde el celular. Lo que puede llevar a horrendos errores gramaticales y ortográficos. Y se debe a que aún no cuento con acceso a internet (Larga historia).

Segundo, el tema de este post. Básicamente hace bastante tiempo venía pensado cómo poder simular algo cercano a AOP pero en Javascript. Claro, no todo el compendio de AOP, o no rigurosamente, pero algo.

Ese algo, para este caso se limitaba a interceptores en las diferentes llamadas a funciones. Como en el caso de lenguajes como C# o Java, dónde es posible decorar una función para obtener un comportamiento previo a la ejecución de la misma.

Un ejemplo es el clásico caso de los controllers de un proyecto MVC. Algo como:

[HttpPost]
public void HacerAlgo() ...

En este caso el decorador hace que dicha función sea ejecutada solo si se produce una llamada de tipo POST.

Por supuesto, esto no es necesariamente AOP. Pero por lo menos nos permite encapsular comportamiento por fuera de la función y esperar el mismo cada vez que decoramos una función.

Entonces el siguiente paso a pensar es: Qué pasaría si quiero escribir un log antes de que la función sea llamada. O mejor aún: Qué pasa si quiero que un set de reglas se ejecute antes de entrar a la función, como por ejemplo, validar que los campos no estén vacios.

[Validar(variable="nombre", empty=false, throwException=true)]
public void MiFuncion(string nombre) ...

En este caso si al llamarse la función la variable nombre se encuentra vacía, entoces se produce una excepción.

Nuevamente, esto no es AOP real, pero para el ejemplo pensemos que es una aproximación.

El punto a evaluar es que podemos obtener conportamiento repetible adicional a nuestra función sin tener que repetir el mismo código dentro del cuerpo de la misma. Y si bien no nos liberamos del acoplamiento, si podemos tener algunos beneficios próximos al mismo.

Tal vez en el caso de AOP, al momento de compilar deberíamos obtener nuevas funciones con dicho código incorporado en ellas. En el ejemplo de C#, por el contrario, necesitamos de un observador que controle el comportamiento de los objetos, clases y funciones, use algún modelo de reflection e inyecte comportamiento mientras las funciones son llamadas.

Esto quiere decir que la estructura de la función no muta en base a nuestras decoraciones.

¿Pero qué pasa con Javascript?

Bueno, resulta un poco más difícil ya que los métodos reflectivos que tenemos disponibles (Hasta donde yo se) no nos permiten decorar y leer esas decoraciones. (Usuarios de React y Redux y demases abstenerse, eso tiene una capita adicional)

Pero sí podemos recrear una función de forma dinámica. Esto es: Tomar la función existente y sobre escribirla a nuestro gusto en tiempo de ejecución.

Toda esta cantaleta para llegar a esto.

En la imagen se puede ver un objeto en el que tenemos una función que recibe dos parámetros. El primero llamado p y el segundo __interceptor. Y es el segundo el que me interesa.

¿Que pasaría si este dictaminará que dicha función, al ser llamada, debiera primero ejecutar alguna acción definida en ese interceptor y luego, si todo sale bien, seguir el camino esperado?

En la imagen lo que terminé armando.

Básicamente la posibilidad de definir dicho interceptor (o varios en cadena). Que modifican el comportamiento original de la función. La sobre escriben y la dejan lista para ser usada con el nuevo código inyectado.

Como vemos en la consola. Al llamar a las diferentes funciones, antes, los interceptores son ejecutados para luego dar paso al código de las funciones originales.

Algunas aclaraciones.

El código es algo largo como para pegarlo en este mismo post por lo que trataré de colocarlo en GitHub en breve.

No lo hice en ES6 o TypeScript por falta de compiladores.

Seguro hay mejores implementaciones. Angular tiene cosas así. PrototypeJs creo que también. Pero ya saben… Es divertido hacerlas uno mismo.

Por último, una vez suba el código aprovecharé para armar otro post explicando algunas partes.

Espero que les resulte interesante 😛


¿Volvemos?

Hace muchísimo tiempo que dejé este blog y lo cambié por los videos en YouTube. Pero mucho contenido creado en esos videos hubiesen funcionado mejor en este espacio.

Por eso, me parece que volveremos por estos lugares. 😉


Semana TIC y Hack@ONG!

Llega el HackatONG 2017

En el marco de la Semana TIC y con el objetivo de crear soluciones tecnológicas para la ciudad de Córdoba y la comunidad en general, el sábado 16 de septiembre se realizará la cuarta edición de el HackatONG en la Legislatura de la Provincia de Córdoba.

A través de este evento abierto y gratuito, la Mesa TIC Córdoba, la comunidad de programadores y actores de la sociedad civil, proponemos fomentar el espíritu colaborativo y el compromiso con ideas y proyectos que resuelvan problemas reales de la ciudadanía a partir del uso de datos dispuestos por diferentes instituciones del sector público y académico.

Durante 10 horas, 200 programadores, diseñadores y líderes de proyectos se reunirán para construir colaborativamente soluciones de software con fin social.

El HackatONG es desde hace cuatro años consecutivos el evento de programación más grande de la provincia de Córdoba.

Este año participarán instituciones y organizaciones locales como por ejemplo Municipalidad de Córdoba, Open Data Córdoba, Fundeps, El Ágora, Fundación Rosas, Fundación Empate, CoderDojo y CONICET Córdoba.

 

Incríbete: http://hackatong2017.eventbrite.com/


Un montón de data

Buenas a todos. Realmente hace mucho que no posteo nada, y en parte ya lo había dicho: He estado haciendo videos de todo.

En este tiempo he subido videos sobre Python, JavaScript, Git, Arduino, e incluso algunos gameplays.

Con el tiempo, es muy probable que el blog quede solo como un histórico de las cosas que decía y todo se resuma a videos, así que, si quieren seguir leyendo (Ahora escuchando y viendo) sobre tecnología, desarrollo y demás, los invito a pasar por el canal en YouTube: https://www.youtube.com/user/LaCosaGorda

Ta luego!


A repartir para que tengan

Por culpa de un compañero de trabajo he caído en la adicción de hacer katas de código en CodeWars. Por supuesto, en uno de mis lenguajes favoritos: JavaScript.

Lo bueno: He arrancado humildemente por los katas de nivel más bajo, con el tino de crear soluciones que están dentro de las que se consideran las más adecuadas (?), o por lo menos, las que se parecen más a las mejor valoradas (Puntito para el ego).

Lo malo: … en realidad no hay nada malo. Se aprende, se ejercita la mente y se aprende (Eso creo que ya lo dije).

Lo que sí resulta importante es que la mayoría de las soluciones, aquellas más valoradas, están siendo hechas en ECMA6. De a poco nuestro viejo y querido JavaScript ha crecido y se hizo adulto. Y por supuesto, nosotros necesitamos crecer con este.

Con lo que me encontré en uno de los katas (Y que claramente ni sabía que estaba por ahí) fue con los (Sí, tres puntos). Un nuevo operador, el operador de dispersión (Calculo que podemos llamarlo de esa forma).

Este operador permite tomar una colección de valores y asignarlos o “traspasarlo” a una lista independiente de valores o variables. De esta forma, si tenemos una función con muchos parámetros, es posible tomar un array y enviarlo como parámetro para que cada uno de los índices del mismo sean asignados a cada una de las variables de la firma (A alguien le suena apply?).

En TypeScript:

let f = (v: any, r: any) => {
  console.log(v, r);
};

var args = ['hola','mundo'];
f(...args);

En el código, cada índice del array irá a parar a cada una de las variables (v y r). Existen otras aplicaciones, pero para eso es cuestión de dejar volar la mente.


Dibujando X en la pantalla

Estoy escribiendo unos artículos que saldrán publicados en fascículos, dentro de muy poco, para aprender a programar desde la óptica de un desarrollador Full Stack (Aquel que puede programar tanto en el cliente como en el servidor). Mientras escribía, me distraje y se me ocurrió hacer un graficador de algunas funciones simples. Si a alguien le interesa, lo dejo por acá.

var canvas = document.createElement('canvas');
canvas.width = 800;
canvas.height = 600;
document.getElementsByTagName('body')[0].appendChild(canvas);
var ctx = canvas.getContext('2d');

function dibujar(f) {
  ctx.clearRect(0, 0, 800, 600);
  var p = 0;

  for (var i = 0; i < 800; i+=0.1) {
    var r = f(i);
    ctx.fillText('x', r[0], r[1]);
  }
}

Y estas son algunas funciones:

var periodo = 0;
var amplitud = 100;
var sobre_eje_y = 200;
var sobre_eje_x = 400;

function seno(tiempo) {
    periodo += 0.01;
    return [tiempo, (Math.sin(periodo) * amplitud) + sobre_eje_y];
}

capture

function coseno(x) {
    periodo += 0.01;
    return [(Math.cos(periodo) * amplitud) + sobre_eje_x, x];
}

capture

function circulo() {
    periodo += 0.1;
    return [(Math.cos(periodo) * amplitud) + sobre_eje_x, (Math.sin(periodo) * amplitud) + sobre_eje_y];
}

capture