Auto-clausuras en JS: el fundamento de las propiedades privadas

En mi anterior post hablé sobre el concepto de clausuras en Java_Script (JS a partir de ahora), y de cómo les podíamos sacar partido en programación avanzada en este lenguaje. En esta ocasión voy a rematar aquello comentando la existencia de auto-clausuras, un concepto muy interesante al que se le puede sacar partido para conseguir algo a priori imposible en este lenguaje: miembros privados en clases JS.


En JS podemos definir una clase de la manera convencional, tratando al mismo tiempo de encapsular el acceso a las variables privadas simulando la existencia de propiedades con funciones ‘get’ y ‘set’, por ejemplo así:

function coche() {
var modelo = «NINGUNO»;
this.getModelo = function () {
return modelo;
};
this.setModelo = function (sModelo) {
modelo = sModelo.toUpperCase();
};
}

var miCoche = new coche;
miCoche.setModelo(«Ferrari»);
alert(miCoche.getModelo()); //Muestra FERRARI


En este caso hemos definido una clase coche que tiene un miembro interno llamado modelo. Para intentar encapsular el acceso a este miembro y poder tener control sobre lo que se hace (que no sea una lectura o escritura directas, vamos) hemos definido dos funciones -que son clausuras– que harán las veces de los métodos getter y setter de una propiedad. De este modo para leer el valor del miembro «privado» usamos getModelo, y para escribirlo setModelo, que en este caso además se ocupa de que el nombre del modelo siempre vaya en letras mayúsculas (por poner un ejemplo de regla de negocio simple y no despistarnos del verdadero objetivo del ejemplo).


Así, si el programador usa estos dos métodos para leer y escribir los miembros privados, como en el ejemplo anterior, todo irá bien. Lo que ocurre es que nadie impide al programador ir directamente a la variable supuestamente privada y hacer esto:

miCoche.modelo = «Ferrari»;
alert(miCoche.modelo); //Muestra Ferrari en minúsculas

Con lo cual todo nuestro esfuerzo no vale absolutamente de nada.


Es posible hacer esto porque en realidad en las clases de JS no existen los miembros privados, ya que no hay modificadores de ámbito (public o private, por ejemplo) que nos permitan controlarlo.


¿Cómo podemos solucionar esto gracias a las clausuras?


Antes de continuar vamos a considerar un ejemplo de código muy sencillo como el siguiente:

  (function (){
var interno = «Valor Interno»;
alert(interno);
}
)();

En este ejemplo hemos definido una función que se llama a si misma, y por lo tanto sólo existe durante el instante en que se ejecuta. No queda rastro de ella una vez que se ejecuta. Sí, es raro y aparentemente no tiene utilidad alguna, pero ten un poco de paciencia.


Lo que estamos definiendo en el fragmento anterior es una función anónima y también una auto-clausura. Es una función que se define, se ejecuta, y luego desaparece sin que pueda volver a ser usada. En realidad no desaparece sino que al no haber una referencia a la misma en ningún lugar de nuestro código no tenemos forma de usarla de nuevo ni de acceder a sus miembros. O sea, en cuanto se ejecuta la variable interna deja de ser accesible en nuestro código pues no hay una referencia a la función en ningún lugar.


¿Qué pasaría si de algún modo pudiésemos definir una función como esta que desaparezca pero quedarnos con una refencia a algo que esté en su interior (una clausura interna de esta función efímera)? Pues pasaría que, de repente, tendríamos acceso a los miembros de esta función efímera pero sólo de manera indirecta, nunca directa como en el caso anterior ya que no tenemos ninuna variable que apunte a la propia función.


Este es el concepto que usaron por primera vez los chicos de Yahoo y que ha permitido definir clases con miembros privados en JS.


Vamos a verlo con un ejemplo práctico reproduciendo la clase anterior que representa a un coche, pero esta vez que sólo sea accesible a través de los métodos getter y setter que hayamos definido:

var coche = function() {
var modelo= «NINGUNO»;
return {
getModelo : function () {
return modelo;
},
setModelo : function (sModelo) {
modelo = sModelo.toUpperCase();
}
};
}();

alert(coche.modelo); //Undefined
alert(coche.getModelo()); //NINGUNO
coche.setModelo(«Smart Fortwo»);
alert(coche.getModelo()); //SMART FORTWO


Fíjate bien en este código como se define una función que se ejecuta inmediatamente poniéndole un (); al final (línea 11), y almacena el resultado de su ejecución en una variable llamada coche. El código interno de esta función define una variable modelo que al igual que antes contendrá el nombre del modelo de coche que estamos manejando. Además como resultado de ejecutar la función se devuelve un nuevo objeto interno que tiene dos métodos que leen o fijan el valor de la variable interna. Como están dentro de la función son dos clausuras que tienen acceso a sus miembros (en este caso la variable modelo), pero como n queda referencia a la función, pues la estamos ejecutanod inmediatamente, entonces la única forma de acceso a la variable modelo que nos queda es a través de esas clausuras. ¡¡Lo que tenemos en la práctica es una variable privada!!. Algo imposible de conseguir a priori. Los alert del final del código anterior nos demuestran que así es. El primero de ellos intenta acceder a la variable modelo pero no puede, porque realmente tiene una refefencia a un objeto interno de la función, no a ésta, así que no puede y devuelve un valor «undefined» ya que no existe dicho miembro para el objeto coche. En las otras tres líneas usamos los métodos «legales» para acceder a la variable y todo funciona correctamente.


Instancias únicas de clase: Singleton


En la práctica ademas obtenemos una clase de instancia única (Singleton), ya que sólo existe una referencia a la misma y no es posible crear nuevas instancias. Esto es muy útil cuando estamos definiendo marcos de trabajo como el mencionado antes de Yahoo, y esta técnica ha sido usada desde entonces por otros frameworks como los mencionados en el post anterior.


Sin embargo nos impide crear clases con miembros privados y que podamos utilizar varias veces. Es decir, tal y como está el código anterior sólo podemos tener un único coche, no varios.


Si quitamos el doble paréntesis de antes (de la línea 11) que fuerza la ejecución, podemos trabajar con ella como si de una clase normal se tratara y seguimos teniendo acceso limitado a los miembros privados:

var Coche = function() {
var modelo= «Ninguno»;
return {
getModelo : function () {
return modelo;
},
setModelo : function (sModelo) {
modelo = sModelo.toUpperCase();
}
};
};

var coche1= new Coche();
var coche2= new Coche();
alert(coche1.modelo); //Undefined
coche1.setModelo(«Porsche»);
coche2.setModelo(«Smart»);
alert(coche1.getModelo()); //PORSCHE
alert(coche2.getModelo()); //SMART


Ahora creamos dos objetos de la clase Coche y les asignamos valores a través de su método setter. Si te fijas en la línea 15, intentamos acceder a su variable privada modelo sin éxito, pues se devuelve un indefinido, así que estamos consiguiendo en la práctica clases con miembros privados y que además podemos instanciar tantas veces como queramos.


Una vuelta de tuerca más al lenguaje de script más popular que tiene una gran utilidad práctica y que espero que te resulte útil 🙂

Closures en BLOCKED SCRIPT una herramienta muy útil

JavaScript es un lenguaje de programación que, a pesar de los años que tiene, cada vez está más de moda y se utiliza más (y no sólo para la web). En los últimos años está viviendo una época dorada que pocos quizá le vaticinaron, gracias sin duda a la popularización de las técnicas AJAX tan necesarias para la Web 2.0.


Desde mediados de los ’90 cualquier programador Web tenía que conocer como mínimo sus fundamentos (de ahí que mi libro sobre el tema vendiera en el año 2.000 un número indecente de ejemplares y fuera de los más vendidos de Amazon en su categoría en todos los idiomas). Sin embargo, lo cierto es que poca gente va más allá de su superficie, y la mayor parte de los programadores Web se quedan en esos fundamentos. Incluso muchos programadores lo rechazan y lo consideran un lenguaje de segunda categoría por ser debilmente tipado e interpretado. Esta misma semana un programador de mi empresa, recién salido de la Universidad, me dijo que en la carrera les desaconsejaban utilizarlo. ¡Lo que es el desconocimiento!


JavaScript es un lenguaje potentísimo que permite hacer verdaderas maravillas bien utilizado. Hay bibliotecas como jQuery, YUIDojo, Microsoft Ajax Library, etc… que son una virguería. Y el lenguaje en sí tiene algunas características únicas que ya quisieran para sí otros lenguajes que a priori son más «profesionales».


Una de estas características es de la que voy a hablar en este post. Se trata de las Closures o Clausuras, provinientes de la programación funcional y muy útiles en algunas ocasiones. Están presentes también en otros lenguajes como C#, Groovy o Lisp. Es muy probable que incluso las hayas utilizado en algún desarrollo de JavaScript sin haberte percatado. Tienen muchas aplicaciones en el actual desarrollo orientado a objetos con JavaScript, por lo que todo programador de JavaScript debería conocerlas.


El ámbito de las variables en JavaScript


Lo habitual cuando trabajamos con JavaScript es fijarnos en que hay dos tipos de ámbitos para las variables: Global y Local. Por ejemplo, en el siguiente fragmento de código JavaScript:

var glo = 1;

function PruebaLocales() {
var loc = 2:
alert(glo); //Muestra un 1
alert(loc); //Muestra un 2
}

alert(glo); //Muestra un 1
alert(loc); //Fallará


La variable global ‘glo’ es accesible desde cualquier parte de nuestro script, ya que se a definido fuera de cualquier otro ámbito, de manera independiente. Sin embargo la variable local ‘loc’ se ha definido dentro de una función, y por lo tanto sólo tiene validez dentro de ésta, y por lo tanto la última instrucción fallará, puesto que estamos intentando llamarla desde fuera de la función.


Como resumen se podría decir que nuestro código puede acceder a variables que tengan un ámbito mayor que en el que se encuentran pero no menor. Así, desde una función sólo podremos acceder a las variables propias de dicha función, que no son accesibles desde otros ámbitos.


La verdadera regla de acceso a variables


Ahora vamos a considerar el siguiente código pefectamente válido en JavaScript:

function pruebaClosure() {
var loc = «¡Hola closure!»;
this.muestraMensaje = function() {
alert(loc);
};
}

var obj = new pruebaClosure();
obj.muestraMensaje(); //Muestra el mensaje de saludo


En este fragmento hemos definido una función/clase que dispone de una función interna definida como método de la clase. Es similar a tener definida una función dentro de otra función (anidada). Lo curioso en este código es que funciona perfectamente y muestra el mensaje contenido en la variable local. Es decir, que en este caso la regla de ámbito parece que se rompe ya que tenemos una función que es capaz de acceder a una variable que no pertenece a la propia función.


Sin embargo no es así y la regla sigue siendo vigente. La verdadera regla de acceso a variables es que una línea de nuestro código sólo puede acceder a variables que tengan un ámbito mayor o igual que el suyo propio. Y en este caso se está cumpliendo ya que la variable ‘loc’ tiene un ámbito mayor que el de la línea de código que lanza la alerta, que tiene un ámbito (el de su función) todavía más restringido.


Piénsalo como una jerarquía donde los niveles inferiores siempre tienen acceso a los superiores. Si estuviésemos hablando de un país la cosa sería que los ciudadanos de una ciudad tienen acceso a los servicios públicos de la ciudad, la región y el país, pero en niveles superiores no es así, de modo que un habitante de la región pero no de la ciudad que estamos considerando tiene acceso a los servicios de la región y del pais, pero no a los de la ciudad por no ser un ciudadano de la misma. Espero haberme explicado 🙂


El verdadero aspecto de las Closures


Las clausuras se llaman así porque en realidad lo que representan es a funciones que tienen acceso a una serie de variables, libres de su propio ámbito (están en un ámbito superior), y que hacen uso de ellas mediante una sintaxis externa que es la que las establece y le da el sentido (las cierra o clausura, de ahí el nombre).


Lo explicaré mejor con un ejemplo más apropiado como el siguiente código JavaScript:

function concatenar(s1) {
return function(s2) {
return s1 + ‘ ‘ + s2;
};
}

var diHola = concatenar(«Hola»);
alert( diHola(«visitante») );


Vaya. Sí que es enrevesado ¿no?. Lo que muestra en pantalla es un mensaje como este:



Es decir, en la práctica gracias al uso de una clausura hemos definido una función que permite asignar valores para ejecución retardada. Esto es algo realmente útil, y no es la única aplicación práctica de las clausuras, pero gracias a ello podemos habilitar todo un sistema de ejecución en diferido de funciones JavaScript. Esto nos permite crear punteros a funciones pre-parametrizadas y con ello crear un sistema de eventos, lanzar acciones periódicas complejas y particularizadas con setInterval o SetTimeout… y muchas otras cosas.


Ejemplo de ejecución diferida


Por ejemplo, consideremos un ejemplo sencillo pero revelador de cómo funcionan estas técnicas que he mencionado. Se trata de lanzar una función con parámetros cada cierto tiempo, con setInterval o con setTimeOut. Esta dos funciones toman como parámetros una referencia a la función a ejecutar y el tiempo en milisegundos al cabo del cual debe ejecutarse (periódicamente o sólo una vez, según sea uno u otro método). Pero tienen una limitación: no permiten pasar parámetros a la función a ejecutar. Así que no sirve para llamar a funciones que tomen parámetros para particularizar su funcionamiento.


La solución chapucera sería definir una función sin parámetros que a su veces llame a la que queremos llamar nosotros con los parámetros requeridos. Una solución mucho más elegante es usar una clausura, como en este ejemplo:

function moverElemento(elto, x, y)
{
return function(){
elto.style = «position:absolute; x:»+ x + «;y:» + «y;»;
};
}
var mover = moverElemento(getElementById(«miDiv»), 0, 0);
setTimeout(mover, 500);

En este caso he utilizado un ejemplo sencillo (la sintaxis de posicionamiento puede que ni esté bien) pero lo que quería ilustrar es cómo usando el artificio de las closures es posible definir punteros a funciones JavaScript parametrizadas en su comportamiento.


Piénsalo y verás las amplias posibilidades que abre. Una de ellas, que contaré en un próximo post es la posibilidad, a priori imposible, de definir variables privadas en objetos JavaScritp, protegiendo el acceso a las mismas de forma que los programadores irresponsables no pudan tocarlas y tengan que ir a través de los cauces que les marquemos.


Las closures abren todo un mundo de posibilidades para la programación JavaScript.


¡Espero que te resulte interesante!

¿Timers o Threads para ejecución de código en servicios Windows?

 

En Krasis Press/campusMVP hemos publicado un nuevo artículo corto.

Esta vez nuestro tutor Alberto Población trata de responder a una pregunta muy común entre los programadores que se aventuran a crear por primera vez un servicio Windows, y es «¿Qué es mejor para ejecutar el código de un servicio Windows? ¿Un Timer o crear hilos?». La respuesta no es tan clara como pueda parecer…

ARTÍCULO: ¿Timers o Threads para ejecución de código en servicios Windows?

¡Esperamos que te sea útil!

ARTÍCULO: Búsqueda de ensamblados en tiempo de ejecución en .NET

Hoy he escrito un pequeño artículo sobre la carga de ensamblados por parte del motor de tiempo de ejecución de .NET. Se trata de algo que no muchos programadores de .NET tienen totalmente claro y que creo que puede resultar de interés general.

En este documento explico los tipos de ensamblados que tenemos en .NET, cómo el motor de tiempo de ejecución de la plataforma busca los diferentes ensamblados que usan nuestras aplicaciones, y cómo podemos incluir referencias a ensamblados de la GAC desde Visual Studio. Finalmente, como apéndice, explicaré un truco para poder ver ensamblados propios en el diálogo de agregar referencia de Visual Studio.

Como ves no hay más que ensamblados por todas partes 😉

Lo he colgado en la página en Scribd de Krasis Press, y lo puedes leer on-line y también descargártelo.

ARTÍCULO: Búsqueda de ensamblados en tiempo de ejecución en .NET

¡Espero que te resulte útil!

WindowUP: coloca cualquier ventana de Windows por encima de las demás

Ayer necesité hacer precisamente eso: que una pequeña ventana que estaba utilizando se quedase por encima de todas las demás para tenerla siempre a la vista. Y de repente me acordé que hace muuuuchos años había desarrollado un programa para hacer precisamente eso. Así que rebusqué en el baúl de los recuerdos y encontré esta joyita. ¡Qué recuerdos!


Se trata de un programa que hice nada más y nada menos que hace 12 años, en 1997, y que está escrito ¡en Visual Basic 3!. Me entran escalofríos sólo de recordarlo. De aquellas ya había por lo menos VB5, asi que seguramente lo hice con VB3 porque entonces casi todos los ordenadores con Windows 95 tenían las DLLs de tiempo de ejecución de VB3 incluidas, y era más «portable». Por fortuna tenía una versión compilada para usarlo, porque, si no, ni de broma me iba a poner a buscar una copia deVB3 para recompilarlo 🙂


Lo alucinante es que funciona igual de bien en Windows 7 hoy en día. Eso es compatiblidad hacia atrás, jeje


El programa WindowUP


Descárgate el ZIP al final de este texto y no tienes ni que instalarlo. haz doble-clic sobre «windowup.exe» y listo, verás esta ventana:



El aspecto delata la antigüedad de la aplicación (bueno, eso y que pone el año en el título).


Para usarlo sólo tienes que pulsar el botón de «Elegir nueva ventana» y al pulsar encima de cualquier ventana que tengas abierta, ésta se añadirá a la lista de la izquierda y a partir de ese instante quedará siempre por encima de las demás. Haz doble click sobre el nombre d ela ventana en la lista para liberarla y que vuelva a ser normal. Puedes elegir tantas ventanas como quieras. Por supuesto puedes elegir la propia ventana del WindowUp para que quede siempre por encima también. Si hasta incluye ayuda, que puede mostrar pulsando en cualquier momento F1.


también puedes usar un truco para hacer que una ventana que está por encima de las demás (y no la has puesto tú con el programa) se convierta en normal. Seleccionala con WindowUP y luego haz doble-clic sobre ella para hacerla normal.


La verdad es que me alegro de haberlo rescatado. En algunas circunstancias puede resultarte útil, y así lo espero.


Descárgatelo desde aquí: WindowUP (238 KB)

Detener un Timer de ASP.NET AJAX

Los temporizadores (Timer) de las extensiones de AJAX para ASP.NET son muy útiles. Nos permiten ejecutar una determinada tarea cada cierto tiempo, provocando postbacks de la página  (tanto completos, como parciales) en intervalos regulares. Un único Timer colocado en la página puede conseguir que se refresquen todos los UpdatePanels disponibles o cada uno de manera individual.


Lo habitual es colocarlos en la página y olvidarnos de ellos. Pero ¿qué pasa si queremos poder pararlos y activarlos a voluntad?


La cosa tiene más complicación de la que parece a simple vista. Lo primero que se nos ocurre a cualquiera es que, dado que tiene una propiedad Enabled para activarlo y desactivarlo bastará con establecerla en False para conseguir el efecto deseado. Si lo hacemos desde un postback asíncrono enviado desde dentro de un UpdatePanel, ni se notará en la página, ¿no?.


Lo malo de esta idea es que, simplemente, no funciona. El motivo es que en un refresco parcial de página, aunque se establezca la propiedad del temporizador, al retornar desde el servidor el cambio no se ve reflejado en el código JavaScript que controla el funcionamiento del mismo (un temporizador no es más que un simple setInterval() de JavaScript de los de toda la vida que provoca por código un refresco parcial de la página).


Entonces, para conseguirlo no nos queda más remedio que controlarlo desde el lado cliente, con JavaScript, lo cual tiene la ventaja añadida de que no es necesario un viaje al servidor para una cosa tan prosaica como esta, así que mejor.


Si observamos el código fuente del control Timer en lado cliente (basta con pulsar F12 en Internet Explorer y ver el código desde la pestaña Script) verás que tiene las siguientes definiciones en su prototipo:


Sys.UI._Timer.prototype = {
get_enabled: Sys$UI$_Timer$get_enabled,
set_enabled: Sys$UI$_Timer$set_enabled,
get_interval: Sys$UI$_Timer$get_interval,
set_interval: Sys$UI$_Timer$set_interval,
get_uniqueID: Sys$UI$_Timer$get_uniqueID,
set_uniqueID: Sys$UI$_Timer$set_uniqueID,
dispose: Sys$UI$_Timer$dispose,
_doPostback: Sys$UI$_Timer$_doPostback,
_handleEndRequest: Sys$UI$_Timer$_handleEndRequest,
initialize: Sys$UI$_Timer$initialize,
_raiseTick: Sys$UI$_Timer$_raiseTick,
_startTimer: Sys$UI$_Timer$_startTimer,
_stopTimer: Sys$UI$_Timer$_stopTimer,
_update: Sys$UI$_Timer$_update
}

Como podemos ver es posible hacer muchas cosas desde lado cliente, en concreto las interesantes son: ver/establecer si está habilitado o no, ver/establecer su intervalo, pararlo y ponerlo de nuevo en marcha.


Sabiendo esto tomar control sobre el timer es muy sencillo, basta con incluir este código JavaScript:


<script language=«javascript» type=«text/javascript»>

var tmr = null;

function ReferenciaTimer() {
if (tmr == null)
tmr = $find(«<%= Timer1.ClientID %>»);
return tmr;
}

function PararTimer() {
ReferenciaTimer()._stopTimer();
}

function LanzarTimer() {
ReferenciaTimer()._startTimer();
}
</script>


Lo único que hago es obtener una referencia al control Timer usando su identificador de cliente (que se «inyecta» desde el servidor al generar la página gracias a una expresión <%= %> de ASP.NET) y la función especial de AJAX $find que sirve para obtener referencias a los componentes en el lado cliente. Luego para pararlo o ponerlo en marcha llamo los método _stopTimer o _startTimer del control JavaScript, que hemos visto en su propotipo. Si colocamos dos botones HTML normales y corrientes que llamen a estas dos funciones que acabo de definir:

   <input id=«Button1» type=«button» value=«Parar Timer» onclick=«PararTimer();» />
<input id=«Button2» type=«button» value=«Lanzar Timer» onclick=«LanzarTimer();» />

¡Listo!


Con esto tenemos controlado el Timer y sin necesidad de ir al servidor para nada. Por supuesto podemo susar un código similar para cambiar o leer su intervalo de refresco o, incluso, para provocar manualmente un evento «tick» que lance el postback asociado al control.


He preparado un pequeño ejemplo práctico con todo lo explicado que puedes descargar desde aquí (3,11 KB)


¡Espero que te sea útil!