<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>A. Matías Quezada</title>
	<atom:link href="http://www.amatiasq.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.amatiasq.com</link>
	<description>Artista de Javascript</description>
	<lastBuildDate>Tue, 30 Apr 2013 23:16:34 +0000</lastBuildDate>
	<language>es-ES</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>ECMAScript 5 _.extend</title>
		<link>http://www.amatiasq.com/2013/04/ecmascript-5-_-extend/</link>
		<comments>http://www.amatiasq.com/2013/04/ecmascript-5-_-extend/#comments</comments>
		<pubDate>Tue, 30 Apr 2013 23:16:34 +0000</pubDate>
		<dc:creator>amatiasq</dc:creator>
				<category><![CDATA[Sin categoría]]></category>

		<guid isPermaLink="false">http://www.amatiasq.com/?p=332</guid>
		<description><![CDATA[A algunos ya os he comentado los problemas que NC Zakas comenta con el _.extend de underscore y los getters: var a = { init: function() { this.list = []; }, get first() { return this.list[0]; } }; O var a = { init: function() { this.list = []; } }; Object.defineProperty(a, 'first', { get: [...]]]></description>
				<content:encoded><![CDATA[<p>A algunos ya os he comentado los problemas que <a href="http://www.nczonline.net/blog/2012/12/11/are-your-mixins-ecmascript-5-compatible/">NC Zakas comenta</a> con el <code>_.extend</code> de underscore y los getters:</p>
<pre><code>var a = {
  init: function() {
    this.list = [];
  },

  get first() {
    return this.list[0];
  }
};
</code></pre>
<p>O</p>
<pre><code>var a = {
  init: function() {
    this.list = [];
  }
};

Object.defineProperty(a, 'first', {
  get: function() {
    return this.list[0];
  }
});
</code></pre>
<p>Y que si hacemos <code>_.extend(a)</code> va a fallar porque intentará hacer <code>result.first = a.first</code> ejecutando el getter. Pero como aún no hemos llamado al <code>.init()</code> en <code>a</code> porque solo es un prototipo, la propiedad <code>.list</code> es undefined produciendo un error.</p>
<p>Pues bien, yo creía que esto se solucionaba extrayendo el descriptor de la propiedad y usando ese mismo descriptor para copiar la propiedad al nuevo objeto:</p>
<pre><code>function extend(obj) {
  var result = {};
  var properties = Object.keys(obj);

  properties.forEach(function(prop) {
    var descriptor = Object.getOwnPropertyDescriptor(obj, prop);
    Object.defineProperty(result, prop, descriptor);
  });

  return result;
}
</code></pre>
<p>Pero he usado esto en la librería de promises y me he dado cuenta que solo hereda las propiedades directas, tanto <code>Object.keys</code> como <code>Object.getOwnPropertyDescriptor</code> solo funcionan si la propiedad está directamente declarada en el objeto y no en ninguno de sus prototipos. Y no hay ninguna forma de decir <code>Object.getPropertyDescriptorFromHimOrHisPrototypes()</code> así que la única forma es recorrer todos los prototipos.</p>
<pre><code>function extend(obj) {
  var result = {};
  var proto = obj;

  while (proto) {
    Object.keys(proto).forEach(function(prop) {
      var descriptor = Object.getOwnPropertyDescriptor(proto, prop);
      Object.defineProperty(result, prop, descriptor);
    });

    proto = Object.getPrototypeOf(proto);
  }

  return result;
}
</code></pre>
<p>Pero eso tampoco funciona del todo bien porque las propiedades de los ancestros se impondrían sobre las propiedades propias del objeto. Así que primero hay que empezar por el último prototipo y acabar por el propio objeto</p>
<pre><code>function extend(obj) {
  var result = {};
  var proto = obj;
  var protos = [];

  while (proto) {
    protos.push(proto);
    proto = Object.getPrototypeOf(proto);
  }

  protos.reverse().forEach(function(ancestor) {
    Object.keys(ancestor).forEach(function(prop) {
      var descriptor = Object.getOwnPropertyDescriptor(ancestor, prop);
      Object.defineProperty(result, prop, descriptor);
    });
  });

  return result;
}
</code></pre>
<p>Y esto ya funciona, pero le falta un detallito, mediante el property descriptor se puede poner que una propiedad no sea enumerable por lo que no se interará sobre ella con un <code>for .. in ..</code> ni con <code>Object.keys</code> pero si las podemos obtener si utilizamos <code>Object.getOwnPropertyNames</code> (Fuente: <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames">MDN</a>). Así que remplazando <code>Object.keys</code> con <code>Object.getOwnPropertyNames</code> esta vez si (espero, rezo, suplico -.-) tenemos una función que crea una copia de todas las propiedades propias y heredadas de un objeto.</p>
<pre><code>function ecma5extend(obj) {
  var proto = obj;
  var protos = [];
  var result = {};

  while (proto) {
    protos.push(proto);
    proto = Object.getPrototypeOf(proto);
  }

  protos.reverse().forEach(function(ancestor) {
    Object.getOwnPropertyNames(ancestor).forEach(function(prop) {
      var descriptor = Object.getOwnPropertyDescriptor(ancestor, prop);
      Object.defineProperty(result, prop, descriptor);
    });
  });

  return result;
}
</code></pre>
<p>Como al final el código ha quedado bastante más complejo de lo que me gustaría lo he apuntado en <a href="https://gist.github.com/amatiasq/5492466">un Gist</a> que podría venirles bien.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.amatiasq.com/2013/04/ecmascript-5-_-extend/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Object.create vs new</title>
		<link>http://www.amatiasq.com/2013/04/object-create-vs-new/</link>
		<comments>http://www.amatiasq.com/2013/04/object-create-vs-new/#comments</comments>
		<pubDate>Thu, 18 Apr 2013 10:15:19 +0000</pubDate>
		<dc:creator>amatiasq</dc:creator>
				<category><![CDATA[Sin categoría]]></category>

		<guid isPermaLink="false">http://www.amatiasq.com/?p=309</guid>
		<description><![CDATA[JotaEseros! Tengo un dilema existencial que me impide dormir. Hasta donde sé los constructores hacen más o menos esto function fakeNew(Ctor) { var instance = Object.create(Ctor.prototype); instance.constructor(); return instance; } Todo empezó cuando quise hacer polyfill de Object.create(), así podría crear objectos sin usar new, decidí usar la versión sencilla Object.create = function(proto) { function [...]]]></description>
				<content:encoded><![CDATA[<p>JotaEseros! Tengo un dilema existencial que me impide dormir.</p>
<p>Hasta donde sé los constructores hacen más o menos esto</p>
<pre><code>function fakeNew(Ctor) {
  var instance = Object.create(Ctor.prototype);
  instance.constructor();
  return instance;
}
</code></pre>
<p>Todo empezó cuando quise hacer polyfill de Object.create(), así podría crear objectos sin usar <code>new</code>, decidí usar la versión sencilla</p>
<pre><code>Object.create = function(proto) {
  function F() { }
  F.prototype = proto;
  return new F();
}
</code></pre>
<p>Y empecé a crear un montón de objetos y a prototiparlos, pero como los objetos muchas veces necesitaban inicializar sus propiedades les hice el método <code>.init()</code></p>
<pre><code>var base = {
  init: function() {
    EmitterMixin.call(this);
    return this;
  }
};

var obj = Object.create(base).init();
</code></pre>
<p>Pero claro, tengo que acordarme de devolver <code>this</code> siempre al acabar <code>.init()</code> y muchas veces lo olvidaba o me olvidaba de invocar <code>.init()</code> que es peor. Así que intentando como simplificar la inicialización de un objeto pensé crear una funcioń global que se encargara de invocar a <code>Object.create</code>, llamar a la función inicializadora y devolver this:</p>
<pre><code>function create(proto) {
  var child = Object.create(proto);
  child.init();
  return child;
}
</code></pre>
<p>Y me empezaron a dar ganas de reventarme la cabeza contra la pared al darme cuenta que <strong>lo que estaba haciendo es prácticamente lo mismo que hace el operador nativo <code>new</code></strong> pero mucho más lento y, en caso de usar el polyfill the <code>Object.create</code> incluso usando <code>new</code> por debajo.</p>
<p>Entonces me pregunto, que beneficios aporta abandonar <code>new</code>? es <a href="http://jsperf.com/object-create-vs-constructor-vs-object-literal/49">notablemente más rápido</a> en la mayoría de navegadores y por la naturaleza de javascript solemos necesitar crear una función inicializadora que en el caso de <code>new</code> es el constructor.</p>
<p>Y lo que es más grave aún, he notado que <strong>usaba dos tipos diferentes de objetos</strong>, unos &#8220;<em>abstractos</em>&#8221; y otros &#8220;<em>instancias</em>&#8221; la mayor diferencia es que en las instancias tenía que invocar <code>.init()</code> siempre mientras que los abstractos no era necesario porque solo serían usados para crear otros objetos que los prototiparan. Y es un patrón que he visto mientras usaba <code>new</code>:</p>
<pre><code>function Foo() { }
Foo.prototype.method = function() { ... };

function Bar() { }
// Objeto "abstracto", no se invoca inicializador
Bar.prototype = Object.create(Foo.prototype);
Bar.prototype.other = function() { ... };

// Objeto "instancia"
// se invoca el constructor como inicializador
var obj = new Bar();
</code></pre>
<p>Realmente hay es una ventaja abandonar <code>new</code>? estamos seguros que no se trata de una herramienta de alto nivel que simplifica algo que igualmente tendremos que hacer nosotros a mano? Que pros y contras tienen <code>new</code> y <code>Object.create</code>?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.amatiasq.com/2013/04/object-create-vs-new/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GIT Workflow (Flujo de trabajo) (Parte 2)</title>
		<link>http://www.amatiasq.com/2012/12/git-workflow-flujo-de-trabajo-parte-2/</link>
		<comments>http://www.amatiasq.com/2012/12/git-workflow-flujo-de-trabajo-parte-2/#comments</comments>
		<pubDate>Tue, 04 Dec 2012 14:57:38 +0000</pubDate>
		<dc:creator>amatiasq</dc:creator>
				<category><![CDATA[Herramientas]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[workflow]]></category>

		<guid isPermaLink="false">http://www.amatiasq.com/?p=269</guid>
		<description><![CDATA[Continuando con mi último artículo, llegó la hora de hablar del gran Github Flow: Github Flow Y finalmente el artículo que ha inspirado éste. Después de probar el Git Flow (el modelo, no la herramienta) en productos profesionales y a modo de prueba en pequeñas librerías propias y aunque para proyectos grandes donde una release [...]]]></description>
				<content:encoded><![CDATA[<p>Continuando con <a href="http://www.amatiasq.com/2012/12/git-workflow-flujo-de-trabajo-parte-1/" title="GIT Workflow (Flujo de trabajo) (Parte 1)">mi último artículo</a>, llegó la hora de hablar del gran <em>Github Flow</em>:</p>
<h3>Github Flow</h3>
<p>Y finalmente <a href="http://scottchacon.com/2011/08/31/github-flow.html">el artículo</a> que ha inspirado éste. Después de probar el Git Flow (el modelo, no la herramienta) en productos profesionales y a modo de prueba en <a href="https://github.com/amatiasq/jsbase">pequeñas librerías</a> propias y <strong>aunque para proyectos grandes donde una release se planea durante semanas va bien, en pequeños proyectos, y en proyectos SaaS no acaba de encajar</strong>.</p>
<p>Para empezar en pequeños proyectos no hay necesidad de planificar con antelación una release, <strong>un proyecto pequeño necesita mucha actividad y poca burocracia para crecer</strong>, por otro lado, en proyectos SaaS (Software as a Serivce), es decir, productos que están disponibles online y todos los usuarios tienen la última versión y reciben los cambios inmediatamente <strong>las versiones y releases pierden fuerza. **Porqué retrasar el lanzamiento de una nueva funcionalidad cuando todos los usuarios podrían tenerla mañana sin ningún coste? en un producto clásico las funcionalidades se empaquetan para entregar al usuario la actualización un paquete cerrado y pasar el proceso de actualización la menor cantidad de veces posibles, pero **en un SaaS para el usuario no tiene ningún coste (en esfuerzo) una actualización</strong>, simplemente la próxima vez que abra el programa tendrá la funcionalidad.</p>
<p>Un ejemplo de SaaS es Gmail (que estuvo más de 5 años en fase Beta por éste motivo), twitter o github. Y es éste último quién, como no podía ser de otra forma, utiliza <strong>un flujo de trabajo de GIT que parece encajar bastante bien con la filosofía SaaS</strong> de release constantes. Lo que ellos llaman <strong><code>Github Flow</code></strong>.</p>
<p><span id="more-269"></span></p>
<p>Como ellos mismos dicen después de mentar las ventajas de git-flow, &#8220;One of the bigger issues for me is that it’s more complicated than I think most developers and development teams actually require&#8221; (Uno de sus mayores problemas para mi es que <strong>[git-flow] es más complicado de lo que creo que muchos equipos de desarrollo realmente necesitan</strong>)</p>
<blockquote>
<p>So, why don’t we use git-flow at GitHub? Well, the main issue is that we deploy all the time.&#8221;<br />
  (Porqué no usamos git-flow en Github? Bueno, el mayor problema es que <strong>nosotros hacemos releases todo el tiempo</strong>).</p>
</blockquote>
<p>Básicamente utilizan un flujo de trabajo que combina la potencia de GIT con las geniales herramientas de Github por lo que es aplicable tal cual a los proyectos alojados en Github.com:</p>
<ul>
<li>El contenido en <code>master</code> es una versión lista para ser utilizada, lo mismo que en git-flow.</li>
<li>Crear ramas descriptivas a partir de <code>master</code> en el repositorio y hacer push constantemente.</li>
<li>Abrir &#8220;Pull Request&#8221; en Github en cualquier momento</li>
<li><strong>Hacer merge a <code>master</code> solo después de una revisión del &#8220;Pull Request&#8221;</strong></li>
<li>Enviar el código a producción inmediatamente después del merge (es decir, enviar a los clientes)</li>
</ul>
<p>Igual que en git-flow, <code>master</code> tiene que ser código estable listo para poner en producción, pero en éste Workflow además debe ser la rama a partir de la cual crear el resto de ramas. En resumen, <strong>cualquier desarrollador puede crear una rama partiendo de <code>master</code> mientras tenga un nombre claro y coherente</strong>, bien sea para corregir un bug o implementar una nueva funcionalidad. A partir de entonces el desarrollador puede hacer todos los commits que necesite y hacer <code>push</code> a la rama en el repositorio constantemente.</p>
<p>En Github mencionan muchas ventajas de ésta fase, en primer lugar, que al hacer pull cada desarrollador recibe información de las ramas en las que hay actividad, y si su nombre es descriptivo es sencillo de analizar. Además <strong>en la página de Github del repositorio podemos consultar las ramas actuales y cuánto se ha avanzado en cada una</strong>, como si de una lista de futuras funcionalidades se tratara (ver imagen artículo original). Por otro lado, los push constantes da visibilidad al resto del equipo de la actividad y garantiza la copia de seguridad de nuestros cambios. Y por fin mi parte favorita, mi descubrimiento del día, los Pull Request de Github.</p>
<p><strong>Un Pull Request consiste en que después de hacer commits y push en una rama, dejamos una notificación de intención de hacer merge a <code>master</code></strong>. Al hacer un Pull Request, en la página de Github del repositorio aparece nuestra notificación con la lista de commits que hemos hecho, y todos los cambios que hemos hecho (en rojo líneas borradas y en verde líneas añadidas). Esto es muy utilizado para ofrecer al dueño de un repositorio un parche o una mejora para que sea aplicado en <code>master</code>, lo que me sorprendió es el uso que le da Github.</p>
<p>A partir de aquí <strong>cualquier usuario puede añadir comentarios a una línea específica del código modificado en los commits</strong>, o un comentario general y abrir debate. Lo que a nivel profesional se conoce como <strong><code>code review</code></strong> (repaso del código) en el que un tercero nos ayuda a repasar nuestros cambios. Esto siempre que se enfoque con una actitud positiva por ambas partes, permite <strong>extender el conocimiento de esa sección del código y detectar bugs con antelación</strong>, simplemente porque cuatro ojos ven más que dos.</p>
<blockquote>
<p>Actually, we use it more as a branch conversation view more than a pull request<br />
  (En realidad, <strong>[los Pull Request] los usamos más como página de conversación sobre la rama que como petición de pull</strong>).</p>
</blockquote>
<p>Según el <em>Github Flow</em> cuando hayamos acabado el desarrollo de la rama o simplemente nos hayamos atascado o necesitamos que un diseñador de el visto bueno al resultado (ya que se pueden adjuntar imágenes a los comentarios con <a href="http://es.wikipedia.org/wiki/Markdown">Markdown</a>), abrimos un Pull Request y <strong>escribiendo @<nombre> en el comentario esa persona recibirá una notificación de nuestro Pull Request</strong>. En Github recomiendan usar &#8220;/cc @<nombre>&#8221; para poner &#8220;En copia&#8221; a los interesados. A medida que recibimos opiniones y recomendaciones de otros usuarios mediante el Pull Request <strong>podemos seguir haciendo commits que automáticamente se añadirán al Pull Request</strong>.</p>
<p>Una vez el trabajo está hecho y hemos pasado el <em>code review</em> esperamos (solicitamos) recibir el visto bueno de algún o varios compañeros</p>
<blockquote>
<p>This is generally a +1 or emoji or “:shipit:”&#8221;<br />
  (Esto suele ser un +1 o el emoticono “:shipit:”)</p>
</blockquote>
<p><strong>Y hayamos pasado los tests, podemos hacer el merge a <code>master</code> nosotros mismos</strong>, cuando hagamos push de <code>master</code> con los cambios aplicados el Pull Request se cerrará automáticamente. Finalmente, inmediatamente después de hacer el merge a <code>master</code> <strong>debemos enviar el código a producción</strong>, que en el caso de Github lo hacen mediante un comando enviado por chat, pero debemos enviar el código inmediatamente a producción para poder detectar posibles bugs con la máxima antelación posible porque si algo nos da mala imagen como desarrolladores es que el trabajo de otra persona falle al ser enviado a producción por algo que nosotros cambiamos y no enviamos. En el artículo original se puede ver una imagen en la que <strong>un solo día se actualizó el código de producción nada menos que 24 veces</strong>. El mismo código que recibimos nosotros al entrar a Github.com</p>
<p>Ha sido largo de explicar, pero quise hacer mucho énfasis en los Pull Request ya que es un uso innovador (al menos para mi) traído de la mano de sus creadores que lo usan activamente por lo que está más que garantizada su fiabilidad. En mi opinión es <strong>el mejor flujo de trabajo para desarrollar productos SaaS</strong>, permitiendo lanzar funcionalidades constante e inmediatamente.</p>
<p>Sin embargo, como todas las grandes metodologías, creo que es muy importante la implicación de todo el equipo en el Workflow. <strong>El Workflow está basado en que un desarrollador sabe esperar a revisar el código a fondo</strong> y recibir feedback antes de hacer el merge a master, y creo que es bastante más complicado de lo que parece superar la tentación de tener el &#8220;trabajo hecho&#8221; pero sin revisar.</p>
<h3>Conclusión A la fecha me encuentro con tres Workflows para trabajar con GIT:</h3>
<p><strong>Git-flow</strong> &#8211; Bastante genérico, en mi opinión si parte del equipo ya conoce ésta metodología es la que utilizaría &#8220;por defecto&#8221; al empezar un proyecto profesional. Y aunque suene evidente, no está de más decir que para pequeños proyectos puede resultar excesivo.</p>
<h5>Pros</h5>
<ul>
<li><strong>Estándar</strong> &#8211; muy conocido en la comunidad GIT</li>
<li><strong>Genérico</strong> &#8211; en mi opinión es fácil adaptar ésta metodología a medida que avanza el proyecto</li>
</ul>
<h5>Cons</h5>
<ul>
<li><strong>Complejo</strong> &#8211; Para una persona comenzando en GIT puede resultar demasiado aprender la secuencia necesaria para cada fase</li>
</ul>
<p><strong>Git-flow con ramas por release</strong> &#8211; No muy recomendable por añadir una complejidad excesiva, pero para los proyectos elefante en los que tenemos tres clientes con versiones distinta puede ahorrarnos tiempo y esfuerzo.</p>
<h5>Pros</h5>
<ul>
<li><strong>Utilidad clara</strong> &#8211; personalmente saber con precisión dónde es útil es una ventaja a la hora de tenerla en considerarlo</li>
</ul>
<h5>Cons</h5>
<ul>
<li><strong>Rebuscado</strong> &#8211; hay que tener cierta experiencia para evitar que ésta metodología se descontrole</li>
</ul>
<p><strong>Github Flow</strong> &#8211; En mi opinión la solución perfecta para un producto SaaS.</p>
<h5>Pros</h5>
<ul>
<li><strong>Probado</strong> &#8211; que éste sistema esté en marcha en Github da mucha confianza, máxime siendo ellos los creadores de una de las mejores herramientas para GIT</li>
</ul>
<h5>Cons</h5>
<ul>
<li><strong>Equipo conscienciado</strong> &#8211; éste Workflow requiere mucha atención ya que constantemente estaremos aplicando código en producción con los riesgos que conlleva para nuestros clientes</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.amatiasq.com/2012/12/git-workflow-flujo-de-trabajo-parte-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>GIT Workflow (Flujo de trabajo) (Parte 1)</title>
		<link>http://www.amatiasq.com/2012/12/git-workflow-flujo-de-trabajo-parte-1/</link>
		<comments>http://www.amatiasq.com/2012/12/git-workflow-flujo-de-trabajo-parte-1/#comments</comments>
		<pubDate>Tue, 04 Dec 2012 14:54:59 +0000</pubDate>
		<dc:creator>amatiasq</dc:creator>
				<category><![CDATA[Herramientas]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[workflow]]></category>

		<guid isPermaLink="false">http://www.amatiasq.com/?p=234</guid>
		<description><![CDATA[Acabo de leer un artículo creado por los trabajadores de Github que han dado una vuelta de tuerca a lo que sabía de GIT y creo que será muy útil compartirlo, pero primero vamos por partes: Control de Versiones Prefiero empezar por lo más básico porque ésto es algo que los programadores damos por hecho [...]]]></description>
				<content:encoded><![CDATA[<p>Acabo de leer <a href="http://scottchacon.com/2011/08/31/github-flow.html">un artículo</a> creado por los trabajadores de <a href="http://www.github.com">Github</a> que han dado una vuelta de tuerca a lo que sabía de GIT y creo que será muy útil compartirlo, pero primero vamos por partes:</p>
<h3>Control de Versiones</h3>
<p>Prefiero empezar por lo más básico porque ésto es algo que los programadores damos por hecho pero para alguien empezando puede ser totalmente desconocido. Una de las herramientas más básicas de un programador junto con el editor de texto es un <strong>sistema de control de versiones</strong>. Se trata básicamente de un programa que <strong>registra los cambios que vamos haciendo en los archivos y cuando nosotros se lo ordenamos (hacemos commit) se guarda el estado actual de los archivos</strong>, si más adelante seguimos haciendo cambio en los archivos y en lugar de mejorar empeora gracias al sistema de control de versiones podemos revertir los archivos y dejarlos tal y como estaban en el último commit o cualquier commit anterior. Además permite que <strong>dos o más personas puedan archivos de un mismo proyecto y cuando ambos envíen sus cambios el sistema hará lo posible por combinarlos</strong> (hacer merge), en caso de que el merge no se pueda hacer automático el sistema notifica un conflicto de cambios y nos pide que lo hagamos a mano.</p>
<p><span id="more-234"></span></p>
<h3>GIT</h3>
<p>Después de usar SVN y TFS y SourceSafe en los cuales hacer merge era dramático o bien imposible (en SourceSafe dos personas no pueden modificar el mismo archivo a la vez), descubrir GIT fue fascinante, <strong>la eficacia con la que resuelve conflictos y la capacidad de crear, combinar y destruir ramas</strong> con un simple comando es una herramienta invaluable. El principal problema con las grandes herramientas es que <strong>hay tantas formas de usarlas que si no sabes lo que haces probablemente te encuentres en un caos</strong> y esa es la sensación que tuve al dar mis primeros pasos con GIT, estar gastando tiempo y esfuerzo en usar una herramienta compleja sin conseguir exprimirle el jugo.</p>
<h3>GIT Flow</h3>
<p>Finalmente me crucé con <a href="http://nvie.com/posts/a-successful-git-branching-model/">GIT Flow</a>, <strong>una guía para aprovechar el potencial de GIT</strong> en el ámbito laboral. La idea es bastante sencilla pero las directrices deben ser respetadas para garantizar el orden:</p>
<ul>
<li>Mantener en la <strong>rama <code>master</code> una versión del código lista</strong> para ser utilizada (production-ready)</li>
<li>Mantener en la <strong>rama <code>develop</code> las nuevas funcionalidades</strong> completas de nuestra aplicación, esperando a que podamos lanzar otra versión estable (release)</li>
<li>Las nuevas funcionalidades se desarrollan en ramas creadas a partir de la rama <code>develop</code> y una vez completadas se &#8220;mergean&#8221; a <code>develop</code></li>
<li>Cuando develop esté listo para una nueva release se abre una rama y se hace la fase final de testing y los cambios de versión. Una vez completada ésta fase la rama de release se &#8220;mergea&#8221; a <code>develop</code> y <code>master</code> y se añade un <code>tag</code> en <code>master</code> para marcar la release.</li>
<li>Los bugs se arreglan en ramas creadas a partir de <code>master</code> y una vez corregidos igual que una rama de release se se actualiza la versión y se &#8220;mergea&#8221; a <code>master</code> y <code>develop</code> y se añade un tag en <code>master</code></li>
</ul>
<p>Para una explicación más detallada recomiendo leer el <a href="http://nvie.com/posts/a-successful-git-branching-model/">artículo original</a> (inglés) ya que lo explica mucho mejor de lo que yo podría. Cada una de éstas operaciones está compuesta de varios comandos git que deben ser ejecutados en un orden dado y es muy común olvidar algún paso, principalmente al empezar con el Workflow, por ello <strong>disponemos de <a href="https://github.com/nvie/gitflow">git-flow</a>, una herramienta que añade comandos a git</strong>. <a href="https://github.com/nvie/gitflow/wiki/Installation">Una vez instalado</a> podremos ejecutar comandos como:</p>
<pre><code>git flow feature start my-feature-name
</code></pre>
<p>Que gestionará por nosotros la creación de la rama a partir de <code>develop</code>. Podemos ver una introducción a git-flow en el artículo <a href="http://jeffkreeftmeijer.com/2010/why-arent-you-using-git-flow/">Why aren&#8217;t you using git-flow?</a> (ingĺés). Aunque no sobra decir que <strong>en el caso de las interfaces gráficas de GIT hay que seguir los pasos manualmente</strong>.</p>
<p>Personalmente creo que éste sistema es bueno si tenemos GIT y no tenemos claro que Workflow seguir. <strong>Es un sistema muy extendido</strong> entre los usuarios de GIT lo que permite que la gente se adapte rápidamente y lo considero un punto medio entre complejidad y simpleza. Hay una variante para proyectos que necesitan mantener más de una versión (es decir, la mayoría de los productos que se venden como paquete cerrado) <strong>en ésta variante en lugar de poner un tag en <code>master</code> por versión creamos una nueva rama</strong>, por ejemplo &#8220;release-1.4&#8243;, de ésta forma disponemos de distintas ramas para cada versión. Ésto nos permite corregir un bug en una versión pasada y sacar un parche específico.</p>
<p>El proceso <strong>al detectar un bug en la última release es probar las releases anteriores hasta detectar la release en la que se introdujo el bug</strong>. Por ejemplo, estamos en la versión 1.8 pero detectamos un bug que afecta a nuestro producto desde la versión 1.2. En ese caso corregimos el bug en una rama creada a partir de la rama de la primera versión que contiene el bug, y una vez corregido se envía a cada rama de release que contenga el bug. Evidentemente <strong>se trata de un Workflow mucho más costoso que no debe ser utilizado a menos que tengamos la necesidad</strong> de mantener más de una versión del producto que por mi experiencia considero una mala práctica, pero si nos encontramos en ésta situación nos puede reducir los problemas y ahorrar mucho tiempo. Continúa en <a href="http://www.amatiasq.com/2012/12/git-workflow-flujo-de-trabajo-parte-2/" title="GIT Workflow (Flujo de trabajo) (Parte 2)">la segunda parte</a>&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.amatiasq.com/2012/12/git-workflow-flujo-de-trabajo-parte-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Experimento: Privacidad por instancias</title>
		<link>http://www.amatiasq.com/2012/03/experimento-privacidad-por-instancias/</link>
		<comments>http://www.amatiasq.com/2012/03/experimento-privacidad-por-instancias/#comments</comments>
		<pubDate>Sat, 03 Mar 2012 15:58:35 +0000</pubDate>
		<dc:creator>amatiasq</dc:creator>
				<category><![CDATA[Experimentos]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.amatiasq.com/?p=208</guid>
		<description><![CDATA[Como ya comenté, la privacidad en Javascript es un tema peliagudo, el lenguaje no nos ofrece ninguna herramienta para gestionar la privacidad automáticamente, tenemos que aprovechar el scope de los closures para ocultar información que el usuario de nuestra librería no necesita saber, pero ocultar propiedades de una instancia es mucho más complicado. Hace algunos [...]]]></description>
				<content:encoded><![CDATA[<p>Como ya comenté, la privacidad en Javascript es un tema peliagudo, <strong>el lenguaje no nos ofrece ninguna herramienta para gestionar la privacidad</strong> automáticamente, tenemos que aprovechar el scope de <strong>los closures para ocultar información</strong> que el usuario de nuestra librería no necesita saber, <strong>pero ocultar propiedades de una instancia es mucho más complicado</strong>. Hace algunos años me empeñé en buscar una forma de conseguir privacidad por instancias que no fuera mediante el constructor, como ya expliqué en el <a href="http://www.amatiasq.com/2012/02/conceptos-basicos-javascript-privacidad/" title="Conceptos Básicos Javascript: Privacidad">post anterior</a>.</p>
<p><span id="more-208"></span></p>
<p>Para empezar está claro que es necesario tener un closure, para ocultar las variables desde fuera:</p>
<pre><code>// función de ejecución inmediata
(function(global) {
    // Contenido oculto
})(this); 
</code></pre>
<p>Dentro de éste closure definiría la clase:</p>
<pre><code>(function(global) {
    function Persona() {
        var secreto;
    }

    Persona.prototype = {
        guardarSecreto: function(susurro) {
            secreto = susurro;
        },
        revelarSecreto: function() {
            return secreto;
        }
    };

    global.Persona = Persona;
})(this);
</code></pre>
<p>Evidentemente es imposible acceder a la variable <code>secreto</code> desde los métodos porque <code>secreto</code> <strong>está encerrada en el constructor y no se puede acceder ella desde fuera</strong> del constructor. Así que si quiero privacidad sin meter los métodos en el constructor por los métodos que <a href="http://www.amatiasq.com/?p=174" title="Conceptos Básicos Javascript: Privacidad">ya expliqué</a> la solución pasa por sacar la variable del constructor:</p>
<pre><code>(function(global) {
    var secreto;

    function Persona() { }
    Persona.prototype = {
        guardarSecreto: function(susurro) {
            secreto = susurro;
        },
        revelarSecreto: function() {
            return secreto;
        }
    };

    global.Persona = Persona;
})(this);

var pepe = new Persona();
var maria = new Persona();
pepe.guardarSecreto('estás en matrix');
console.log(maria.revelarSecreto());
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/eXfkL/" target="_blank">Pruébame</a></p>
<p>Bien, ahora <code>secreto</code> está fuera del constructor, pero tenemos otro problema, <strong>todas las instancias de <code>Persona</code> comparten la misma variable!</strong> Hay que buscar la forma de contar un secreto a <code>pepe</code> sin que <code>maria</code> se entere, dicho de otra forma, de guardar un valor en una instancia sin modificar la otra. En Javascript es muy sencillo trabajar con mappings así que porqué no guardamos en un mapping la relación instancia-valor? Así cada instancia podrá tener su valor guardado en la variable secreto sin interferir con el valor de otra instancia.</p>
<pre><code>(function(global) {
    var secreto = {};

    function Persona() { }
    Persona.prototype = {
        guardarSecreto: function(susurro) {
            secreto[this] = susurro;
        },
        revelarSecreto: function() {
            return secreto[this];
        }
    };

    global.Persona = Persona;
})(this);

var pepe = new Persona();
var maria = new Persona();
pepe.guardarSecreto('estás en matrix');
console.log(maria.revelarSecreto());
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/NaphB/" target="_blank">Pruébame</a></p>
<p>Esto tampoco funciona, porqué? Para entender ésto hay que investigar un poco, <strong>los índices de los arrays y los mappings en Javascript son <code>strings</code></strong>, y si intentas poner un índice de otro tipo lo convierte a <code>string</code> con el método <code>.toString()</code></p>
<pre><code>var array = [];
array[0] = "Hola!";

for (var i in array) {
    if (array.hasOwnProperty(i)) {
        console.log("Array tiene la propiedad --[" + i + "]-- del tipo --[" + (typeof i) + "]-- con el valor --[" + array[i] + "]--");
    }
}

var mapping = {};
var indice = {};
mapping[indice] = "Mundo!";

for (var i in mapping) {
    if (mapping.hasOwnProperty(i)) {
        console.log("Mapping tiene la propiedad --[" + i + "]-- del tipo --[" + (typeof i) + "]-- con el valor --[" + mapping[i] + "]--");
    }
} 
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/cQZmS/" target="_blank">Pruébame</a></p>
<p>Entonces <strong>tanto <code>pepe</code> como <code>maria</code> se convierten a <code>[object Object]</code> cuando los utilizo como índices</strong> del mapping. Y hasta aquí había llegado hasta que descubrí los <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/WeakMap"><code>WeakMap</code> de Firefox</a>. Consiste básicamente en una clase con métodos <code>.set(id, valor);</code> y <code>.get(id);</code> por lo que cumple la misma funcionalidad que un mapping, con la diferencia de que si el único punto del programa en el que se usa una referencia es un <code>WeakMap</code>, <strong>el recolector de basura la puede borrar</strong>. Es una funcionalidad que es necesaria en Javascript por motivos que no voy a enumerar ahora, pero para mi trae un éxtra: &#8220;WeakMaps are key/value maps in which <strong>keys are objects</strong>&#8221; (Los WeakMaps son mappings clave/valor donde <strong>las claves son objetos</strong>). Sorpresa! Los <code>WeakMap</code> a diferencia de los mappings comunes no usan strings como claves, sino objetos. Esto haría viable la implementación anterior:</p>
<pre><code>(function(global) {
    var secreto = new WeakMap();

    function Persona() { }
    Persona.prototype = {
        guardarSecreto: function(susurro) {
            secreto.set(this, susurro);
        },
        revelarSecreto: function() {
            // Si no tenemos ningún secreto
            if (!secreto.has(this))
                return "Nada";
            else
                return secreto.get(this);
        }
    };

    global.Persona = Persona;
})(this);

var pepe = new Persona();
var maria = new Persona();

pepe.guardarSecreto('estás en matrix');
console.log("Secreto de María: " + maria.revelarSecreto());
console.log("Secreto de Pepe: " + pepe.revelarSecreto());
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/dAzjx/" target="_blank">Pruébame</a></p>
<p><strong>Nota</strong>: Aunque los WeakMap solo están en Firefox, ésto funcionará en todos los navegadores porque he creado una clase que se comporta de forma similar, pero que no permite al recolector de basura eliminar los objetos, la implementación puede verse al final del artículo.</p>
<p>Funciona! Hemos conseguido guardar una variable privada por instancia con un closure por clase. Ahora llémoslo un poco más allá, que pasa si <strong>en lugar de guardar una variable guardamos un objeto donde podremos tener todas las variables que queramos</strong> para ésa instancia?</p>
<pre><code>(function(global) {
    var privadas = new WeakMap();

    function Persona() {
        // Inicializamos el objeto
        privadas.set(this, {});
        privadas.get(this).otraPrivada = "Variable inaccesible desde fuera";
    }

    Persona.prototype = {
        guardarSecreto: function(susurro) {
            privadas.get(this).secreto = susurro;
        },
        revelarSecreto: function() {
            return privadas.get(this).secreto;
        }
    };

    global.Persona = Persona;
})(this);

var pepe = new Persona();
var maria = new Persona();

pepe.guardarSecreto('estás en matrix');
console.log("Secreto de María: " + maria.revelarSecreto());
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/RzDAE/" target="_blank">Pruébame</a></p>
<p>Perfecto, pero es un poco raro y repetitivo tener que hacer <em>privadas.set(this, {});</em> en el constructor y <em>privadas.get(this)</em> pra acceder a las privadas, podríamos encapsular ésto en una función:</p>
<pre><code>function privadas() {
    var map = new WeakMap();
    return function(clave) {
        if (!map.has(clave))
            map.set(clave, {});
        return map.get(clave);
    };
}
</code></pre>
<p>Y ahora ésta funcion nos devuelve otra función que podremos llamar cuando queramos con la instancia para obtener las privadas. Nuestra clase queda:</p>
<pre><code>(function(global) {
    var p = privadas();

    function Persona() {
        p(this).secreto = "Nada";
        p(this).otraPrivada = "Variable inaccesible desde fuera";
    }

    Persona.prototype = {
        guardarSecreto: function(susurro) {
            p(this).secreto = susurro;
        },
        revelarSecreto: function() {
            return p(this).secreto;
        }
    };

    global.Persona = Persona;
})(this);

var pepe = new Persona();
var maria = new Persona();

pepe.guardarSecreto('estás en matrix');
console.log("Secreto de María: " + maria.revelarSecreto());
console.log("Secreto de Pepe: " + pepe.revelarSecreto());
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/XmKCH/" target="_blank">Pruébame</a></p>
<p>Y voilá! Tenemos privadas por clases sin crear más de un closure. <img src='http://www.amatiasq.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<h3>Resumen</h3>
<p>Está claro que <strong>es aberrante pensar en crear una arquitectura basada en éste sistema</strong>, incluso dejando de lado lo extraño de la sintaxis (<code>p(this)</code> para acceder a las privadas), <strong>sería peligroso</strong> porque aunque Firefox nos ofrezca <code>WeakMap</code> en el resto de navegadores tendríamos que crear una funcionalidad similiar y no podríamos evitar tener una referencia a las instancias si queremos que el sistema sea irrompible, lo que haría que el recolector de basura no pudiera borrar las instancias que ya no utilizemos con <strong>riesgo de llenar la memoria RAM disponible</strong>.</p>
<p>Como ya he dicho muchas veces, la gracia de <strong>esto no es forzar Javascript a su límite, sino forzar la mente</strong>, si hoy forzamos la imaginación hasta sus límites mañana podremos sobrepasarlos. La idea es ejercitar y mejorar la capacidad de buscar soluciones creativas y funcionales por extrañas o imposibles que parezcan.</p>
<p>Finalmente, como expliqué en la nota, aquí está la implementación que usé para que los ejemplos funcionen en navegadores que no sean Firefox, guarda en los objetos la propiedad <em>$$ID</em> para no tener que buscar en todo el array de claves el índice del objeto:</p>
<pre><code>if (typeof WeakMap === 'undefined') {
    window.WeakMap = function WeakMap() {
        this.keys = [];
        this.values = [];
    }
    WeakMap.prototype = {
        constructor: WeakMap,

        set: function(key, value) {
            var id = key.$$ID = this.keys.length;
            this.keys[id] = key;
            this.values[id] = value;
        },

        get: function(key) {
            var id = key.$$ID;

            // Si el índice del objeto no se corresponde
            // con su posición en la lista de claves
            // Es que ha sido modificado, debemos corregirlo.
            if (this.keys[id] !== key)
                id = this._fixIndex(key);

            return this.values[id];
        },

        has: function(key) {
            return this._fixIndex(key) !== null;
        },

        _fixIndex: function(key) {
            for (var i = this.keys.length; i--; )
                if (this.keys[i] === key)
                    return key.$$ID = i;
            return null;
        }
    };
}
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.amatiasq.com/2012/03/experimento-privacidad-por-instancias/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Conceptos Básicos Javascript: Privacidad</title>
		<link>http://www.amatiasq.com/2012/02/conceptos-basicos-javascript-privacidad/</link>
		<comments>http://www.amatiasq.com/2012/02/conceptos-basicos-javascript-privacidad/#comments</comments>
		<pubDate>Sun, 26 Feb 2012 18:30:38 +0000</pubDate>
		<dc:creator>amatiasq</dc:creator>
				<category><![CDATA[Conceptos Básicos de Javascript]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.amatiasq.com/?p=174</guid>
		<description><![CDATA[Introducción Uno de los temas más frecuentes cuando uno se inicia en Javascript es la privacidad, principalmente viniendo de lenguajes como Java, C# o C++; donde publican o se ocultan propiedades de los objetos mediante modificadores. Javascript no posee dichos modificadores sino que todas las propiedades de los objetos son públicas lo que puede ser [...]]]></description>
				<content:encoded><![CDATA[<h3>Introducción</h3>
<p>Uno de los temas más frecuentes cuando uno se inicia en Javascript es la privacidad, principalmente viniendo de <strong>lenguajes como Java, C# o C++; donde publican o se ocultan propiedades de los objetos mediante modificadores. Javascript</strong> no posee dichos modificadores sino que <strong>todas las propiedades de los objetos son públicas</strong> lo que puede ser muy confuso para una persona poco diestra en ésta técnica, entre los que me incluyo.</p>
<p>Personalmente cuando diseño un componente (objeto/clase/librería), es porque quiero que ese componente cumpla una funcionalidad, por ejemplo, si yo quiero tener una clase que represente a una impresora necesito enviarle datos y que los imprima; <strong>mi prioridad es que dicho componente sea sencillo de utilizar, lo que facilita la reutilización del componente</strong>. Por lo que primero imagino cómo me gustaría usarlo:</p>
<pre><code>var impresora = new Impresora();
impresora.encender();
impresora.imprimir(datos);
impresora.apagar();
</code></pre>
<p>Como se ve, para cumplir la funcionalidad me basta con tres métodos, pero si yo escribo mi clase impresora con solo tres métodos probablemente duplicaría mucho código, por ejemplo, que <code>.imprimir()</code> y <code>.apagar()</code> deban comprobar si hay papel en la impresora.</p>
<p><span id="more-174"></span></p>
<h3>Soluciones</h3>
<h4>Hacer toda la interfaz pública</h4>
<p>Podríamos crear in método público <code>.hayPapel()</code>, pero personalmente prefiero que la API, la interfaz pública de mi componente sea tan sencilla como sea posible por lo que no quiero hacer ése método público. <strong>Cuando tengo que usar una librería ajena no quiero saber cómo está hecha, quiero saber como usarla</strong>. Por ello si ésta clase tiene el método <code>.hayPapel()</code> le estoy diciendo al programador que ese método está ahí para usarlo, cuando en realidad no es así, ese método está ahí para ayudarme a mi como desarrollador de la clase a no duplicar código.</p>
<h4>Usar la convención de Barra Baja (Underscore, &#8216;<code>_</code>&#8216;)</h4>
<p>Una práctica muy común en Javascript es añadir al principio o al final del nombre de la propiedad el símbolo barra baja con lo que la propiedad es pública, pero <strong>por convención las propiedades que empiezan o finalizan con barra baja no deben ser llamadas desde fuera del componente</strong>:</p>
<pre><code>function Impresora() { }
Impresora.prototype = {
    encender: function() { ... },
    apagar: function() { ... },
    imprimir: function(datos) { ... },
    _hayPapel: function() { ... }
}; 
</code></pre>
<p>Este es el método más extendido que he visto en Javascript, porque es una solución que <strong>no afecta al tiempo de ejecución del programa</strong>. Javascript simplemente accede a una propiedad pública sin pérdida de rendimiento. Es una buena solución siempre que se respete la convención, de lo contrario estaríamos acoplando componentes. Eso quiere decir que si quiero hacer pública una propiedad tengo que cambiarle el nombre en todos los puntos en que la utilizo? Desgraciadamente si, pero siempre tienes el consuelo de que será dentro de tu propia librería, ya que si cambias una variable de privada a pública no debería haber ningún punto fuera de tu código que accediera a ésa propiedad, y si lo que estás haciendo es cambiarla de pública a privada&#8230; bueno, evidentemente hay que refactorizar el código que utilizara tu librería de cualquier forma.</p>
<h4>Privacidad por constructor</h4>
<p>Los closures son un curioso método de privacidad, cuando creamos una función dentro de otra, <strong>la función hija puede acceder a las variables de la función padre, pero no al revés</strong>:</p>
<pre><code>var a = 5;

function() {
    var b = 6;

    function() {
        var c = 7;
        // Desde aquí puedo acceder a 'a', 'b' y 'c'
    }

    // Desde aquí puedo acceder a 'a' y 'b'.
    // 'c' no existe
}

// Desde aquí solo puedo acceder a 'a'.
// 'b' y 'c' no existen 
</code></pre>
<p>Con ésto podemos buscar la privacidad, si analizamos el constructor de la clase <code>Impresora</code> veremos que es una función, igual que las del ejemplo. De alguna forma <strong>podemos crear variables privadas ahí</strong>.</p>
<pre><code>function Impresora() {
    var a = "Privada!";
    console.log("Accediendo desde dentro:" + a);
}

var temp = new Impresora();
console.log("Intentando acceder desde fuera usando 'temp.a': " + temp.a);

// Esta línea no se ejecuta porque 'a' no existe aquí y falla.
console.log("Intentando acceder desde fuera usando 'a': " + a);
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/qJnvS/" target="_blank">Pruébame</a></p>
<p>Funciona! Ahora añadamos los métodos:</p>
<pre><code>function Impresora() {
    var a = "Privada!";
}

Impresora.prototype = {
    probando: function() {
        console.log("Intentando acceder desde un método usando 'this.a': " + this.a);

        // Esta línea no se ejecuta porque 'a' no existe aquí y falla.
        console.log("Intentando acceder desde un método usando 'a': " + a);
    }
};

var temp = new Impresora();
temp.probando(); 
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/jQLQf/" target="_blank">Pruébame</a></p>
<p>Pero no podemos acceder desde los métodos! <strong>Porque no están dentro del closure</strong>, de que nos sirve una variable privada si no podemos acceder a ella desde los métodos públicos? Hay una solución: el closure en el que hemos guardado la variable privada es el constructor del objeto, por lo que podríamos aprovechar el dinamismo de Javascript e injectar los métodos en el objeto dentro del constructor, así los métodos podrían acceder a las variables privadas:</p>
<pre><code>function Impresora() {
    var a = "Privada!";

    // This es el objeto que éste constructor está creando
    this.probando = function() {
        console.log("Intentando acceder desde un método usando 'this.a': " + this.a);
        console.log("Intentando acceder desde un método usando 'a': " + a);
    };
}

var temp = new Impresora();
temp.probando(); 
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/gRVqv/" target="_blank">Pruébame</a></p>
<p>Bien! éste sistema funciona, verdad? No tiene ningún inconveniente? Bueno, tiene uno, pero no es visible a simple vista porque nuestro cerebro y el intérprete de Javascript funcionan de forma distinta. <strong>Para nosotros <code>this.probando = function() { ... }</code> es crear una función y añadirla a todos las instancias de <code>Impresora</code></strong> pero el intérprete no lo ve así, para la máquina Javascript <strong>estamos creando una función por cada método para cada instancia</strong> y tiene sentido, si la primera función <code>probando</code> que creamos accede a la variable privada <code>a</code> de la primera instancia que creamos necesitaremos una función distinta para acceder a la variable privada de la segunda instancia que creemos.</p>
<p>Eso quiere decir que <strong>si creamos 10.000 instancias de <code>Impresora</code> tendremos 10.000 funciones que hacen casi lo mismo en la memoria? Si.</strong> Con las computadoras actuales es casi despreciable, pero si estamos manejando un proyecto en Javascript que puede estar creando y borrando instancias de la clase durante días (por ejemplo un programa de servidor o una RIA), tendremos un problema a medio plazo.</p>
<h3>Privacidad de librería</h3>
<p>Ahora tengo que confesar que he hecho trampas, todos los patrones descritos son para hacer privacidad a nivel de clase, pero <strong>hay una forma más sencilla de hacer privada una clase entera, los closures</strong>. Ahora pensarás &#8220;pero me acabas de decir que los closures volvían a crear los métodos por cada instancia!&#8221; si, cuando el closure es el constructor. <strong>Pero si englobamos toda la clase en un closure podemos tener privacidad a nivel de librería:</strong></p>
<pre><code>// función de ejecución inmediata, se crea, se ejecuta y no se vuelve a utilizar
// es el closure que guardará la privacidad
(function(global) {
    var contador = 0;

    function Impresora() {
        contador++;
    }

    // Creamos un método estático
    Impresora.cantidadDeInstancias = function() {
        return contador;
    };

    global.Impresora = Impresora;
})(this);

var temp = new Impresora();
var temp2 = new Impresora();
console.log(Impresora.cantidadDeInstancias());
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/HJzAB/" target="_blank">Pruébame</a></p>
<p>La variable <code>contador</code> es <strong>privada a nivel de librería</strong>, significa que <strong>todo lo que esté dentro del closure accede a ella</strong> y como podemos ver todo el código dentro del closure accede a la misma variable, lo que significa que todas las instancias de <code>Impresora</code> comparten la misma variable. También podemos usar éste patrón para ocultar clases y funciones, <strong>lo único que será publicado de dentro del closure será lo que guardemos en la variable <code>global</code>.</strong></p>
<pre><code>// función de ejecución inmediata, se crea, se ejecuta y no se vuelve a utilizar
// es el closure que guardará la privacidad
(function(global) {
    function Papel() { }
    Papel.prototype = {
        hayPapelEn: function(impresora) {
            // no hay papel
            return false;
        },
        pedirAlUsuario: function() {
            console.log("Oye tu! ponme papel!");
        }
    };

    var papel = new Papel();

    function Impresora() { }
    Impresora.prototype = {
        imprimir: function(datos) {
            if (!papel.hayPapelEn(this))
                papel.pedirAlUsuario();
            // imprimir
        }
    };

    global.Impresora = Impresora;
})(this);

var temp = new Impresora();
temp.imprimir();
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/vc2ke/" target="_blank">Pruébame</a></p>
<p>Este es un patrón muy recomendable, ya que mediante una función autoejecutable ocultamos todo lo que el usuario de nuestra librería no necesita conocer. Por poner un ejemplo, <a href="http://nodejs.org/">node.js</a> utiliza un patrón similar para generar librerías, en las que todas las variables que creamos en el archivo .js quedan ocultas y solo se exponen las propiedades que añadimos al objeto global <code>exports</code>. Ejemplo de saludo.js:</p>
<pre><code>var saludo = "Hola!";
function saludar() {
    console.log(saludo);
}
exports.saludar = saludar; 
</code></pre>
<p>Si tuviera que decir un defecto de éste patrón, es que <strong>todo lo que queramos englobar dentro del closure deberá estar en el mismo archivo</strong>, ya que el código debe estar dentro del closure y éste no puede estar repartido entre archivos. Ésto es un problema si queremos que dos clases con mucha lógica se comuniquen y no queremos acabar con un archivo de 1.000 líneas de código.</p>
<h3>Resumen</h3>
<p>No voy a opinar si la decisión de hacer todo público al crear Javascript es buena o mala porque en mi opinión <strong>no es que hacer todo público sea malo, sino que no estamos acostrumbrados a utilizarlo</strong>. Por ello, porque la mayoría de los programadores estamos acostumbrado a tener privacidad en los componentes, buscamos entre las opciones que nos da el lenguaje para simularlo.</p>
<p>En cuanto a mi, me parece interesante las posibilidades de un lenguaje tan flexible como Javascript a nivel académico, al fin y al cabo el objetivo de la investigación es tener la mente flexible para que a la hora de la verdad podamos ver caminos alternativos que nos ofrecen una mejor solución para un problema en particular. Un ejemplo de ésto es un patrón de privacidad por instancia que descubrí recientemente, hablaré de él en el <a href="http://www.amatiasq.com/?p=208" title="Experimento: Privacidad por instancias">próximo post</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.amatiasq.com/2012/02/conceptos-basicos-javascript-privacidad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Javascript Conceptos Básicos: Herencia por prototipos</title>
		<link>http://www.amatiasq.com/2012/01/javascript-conceptos-basicos-herencia-por-prototipos/</link>
		<comments>http://www.amatiasq.com/2012/01/javascript-conceptos-basicos-herencia-por-prototipos/#comments</comments>
		<pubDate>Wed, 18 Jan 2012 12:24:05 +0000</pubDate>
		<dc:creator>amatiasq</dc:creator>
				<category><![CDATA[Conceptos Básicos de Javascript]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[clases]]></category>
		<category><![CDATA[conceptos basicos]]></category>
		<category><![CDATA[extender]]></category>
		<category><![CDATA[herencia]]></category>
		<category><![CDATA[heritage]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[object oriented programming]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[poo]]></category>
		<category><![CDATA[programacion orientada a objetos]]></category>
		<category><![CDATA[prototype]]></category>

		<guid isPermaLink="false">http://www.seldaiendil.com/amatiasq/?p=167</guid>
		<description><![CDATA[Llegó la hora de entrar el en tema que realmente confunde a los recién llegados a Javascript, principalmente para quienes vienen de lenguajes que implementan la orientación a objetos mediante clases, que son la gran mayoría. Orientación a Objetos Primero deberemos aclarar que significa Programación Orientada a Objetos (POO u OOP en ingés). Según la [...]]]></description>
				<content:encoded><![CDATA[<p>Llegó la hora de entrar el en tema que realmente confunde a los recién llegados a Javascript, principalmente para quienes vienen de lenguajes que implementan la orientación a objetos mediante clases, que son la gran mayoría.</p>
<h3>Orientación a Objetos</h3>
<p>Primero deberemos aclarar que significa Programación Orientada a Objetos (POO u OOP en ingés).</p>
<p><a href="https://es.wikipedia.org/wiki/Programaci%C3%B3n_orientada_a_objetos">Según la Wikipedia</a>, la descripción es:</p>
<blockquote>
<p>es un paradigma de programación que usa objetos y sus interacciones, para diseñar aplicaciones y programas informáticos. Está basado en varias técnicas, incluyendo herencia, abstracción, polimorfismo y encapsulamiento.</p>
</blockquote>
<p>Como vemos un lenguaje orientado a objetos <strong>no necesariamente tiene que implementarse mediante clases</strong>, cualquier sistema que proporcione <a href="https://es.wikipedia.org/wiki/Herencia_(programaci%C3%B3n_orientada_a_objetos)">herencia</a>, <a href="https://es.wikipedia.org/wiki/Abstracci%C3%B3n_(programaci%C3%B3n_orientada_a_objetos)">abstracción</a>, <a href="https://es.wikipedia.org/wiki/Polimorfismo_(programaci%C3%B3n_orientada_a_objetos)">polimorfismo</a> y <a href="https://es.wikipedia.org/wiki/Encapsulamiento_(programaci%C3%B3n_orientada_a_objetos)">encapsulamiento</a> es una implementación de orientación a objetos válida. Como ya dijimos, el sistema de clases es el más extendido, utilizado por C++, Java, C#, PHP, Python, ActionScript3, Perl, Objective-C, Ruby, etc&#8230; <strong>Javascript no tiene clases, utiliza el sistema de herencia por prototipos</strong>, veamos la diferencia:</p>
<p><span id="more-167"></span></p>
<p><strong>En un lenguaje basado en clases</strong> tenemos dos tipos de conceptos, los objetos en sí, referencias que pueden ser almacenadas, modificadas y pasadas como argumentos. Y por otro lado <strong>las clases, objetos intangibles, no podemos guardarlos en variables ni pasar como argumento</strong>, no podemos manipularlos ni comprobar si existen excepto por reflexión, que consiste en herramientas del lenguaje para obtener objetos (tangibles, del tipo anterior) que <strong>representan a las clases</strong> a las que no podemos acceder. En un lenguaje de éste tipo las clases están una capa por encima de los objetos y definen la herencia, abstracción, encapsulamiento y polimorfismo de los objetos que se obtendrán a partir de ellas, tienen una función de plantillas para crear objetos definidas antes de ejecutarse el código del programa.</p>
<p><strong>En un lenguaje orientado a prototipos</strong> no hay clases que definan la herencia, los objetos mismos heredan de otros objetos. No hay clases cuando el programa se inicia, sino que se crean objetos y se le ordena a otros objetos que hereden de ellos. Por ejemplo, si tenemos un objeto eventEmitter y queremos crear instancias creamos nuevos objetos y hacemos que hereden de eventEmitter.</p>
<h3>[[Prototype]]</h3>
<p>Una vez entendido el concepto podemos pasar a la práctica, sabemos que para crear instancias de clases hacemos <code>new MyClass()</code> pero cómo hacemos que objetos hereden de objetos? Aquí entran los prototipos. <strong>Todos los objetos Javascript tienen una propiedad oculta que llamaremos <code>[[Prototype]]</code></strong>, con corchetes (aunque en algunos navegadores es posible acceder a ella mediante la propiedad <code>.__proto__</code>, con dos barras bajas a cada lado, pero no es estándar) <strong>que es un puntero al objeto del cual hereda</strong>. Y que significa que hereda? Podríamos resumir la herencia en que un objeto tiene las mismas propiedades que otro.</p>
<p>Con ésto nos ahorramos tener que poner las mismas propiedades en más de un objeto. Esto trae un nuevo concepto que puede confundir a muchos: <strong>en Javascript todo es una instancia, y cuando heredamos de un objeto también se puede decir que estamos creando una instancia de ése objeto</strong>, para evitar confunsiones <strong>suele decirse que un objeto &#8220;extiende&#8221; otro</strong>. Imaginemos que tenemos un objeto perro que hereda de animal. Que significa ésto? que la propiedad <code>[[Prototype]]</code> de perro es animal, o lo que es lo mismo:</p>
<pre><code>perro.__proto__ == animal; // true
</code></pre>
<p>El código de ejemplo es el siguiente:</p>
<pre><code>var animal = {};
animal.estaVivo = function() {
    return true;
};

var perro = {};
perro.__proto__ = animal;
console.log(perro.estaVivo);
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/tyK4u/" target="_blank">Pruébame</a></p>
<p>Vemos que <code>perro.estaVivo</code> es la función que asignamos a <code>animal</code> cómo puede ser ésto? Por la herencia por prototipos. <strong>Javascript ha buscado la propiedad <code>estaVivo</code> en <code>perro</code> pero no la ha encontrado, entonces accede a su propiedad <code>[[Prototype]]</code> (o <code>__proto__</code>)</strong> donde nosotros guardamos <code>animal</code>. Entonces busca <code>estaVivo</code> en <code>animal</code> y lo encuentra. Por eso <code>perro.estaVivo</code> nos devuelve el método de <code>animal</code>. Podríamos representarlo así:</p>
<p><img src="/wp-content/uploads/2012/01/prototype.png" alt="Diagrama" /></p>
<p>Y si animal no hubiese tenido la propiedad <code>estaVivo</code>? En ese caso debemos tener en cuenta que animal también es un objeto y que todos los objetos tienen prototipo, en caso de que no le asignemos ninguno su prototipo es <code>Object.prototype</code>. Es otra forma de decir que <strong>en Javascript todos los objetos extienden <code>Object.prototype</code></strong>. <code>Object.prototype</code> es el equivalente a la clase <code>Object</code> de Java o C#.</p>
<pre><code>var animal = {};
console.log(animal.__proto__ === Object.prototype);
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/29S2r/" target="_blank">Pruébame</a></p>
<p>Y si tampoco encuentra la propiedad en <code>Object.prototype</code>? lo busca en el <code>[[Prototype]]</code> de <code>Object.prototype</code> pero sorpresa! <strong><code>Object.prototype.__proto__</code> es <code>null</code></strong>. Eso significa que <strong>es el último objeto de la jerarquía de herencia</strong>, si llegado a éste punto Javascript no encuentra la propiedad que le pedimos devuelve <code>undefined</code>.</p>
<p>Esta jerarquía de prototipos suele llamarse <strong>cadena de prototipos</strong> del objeto. Por ejemplo, <code>Object.prototype</code> tiene la propiedad <code>.toString()</code>, entonces si volvemos a crear <code>perro</code> heredando de <code>animal</code>, su propiedad <code>.toString()</code> que será? Javascript recorrerá la jerarquía de prototipos de <code>perro</code> hasta encontrar <code>.toString()</code> que está en <code>Object.prototype</code>.</p>
<pre><code>var animal = {};
animal.estaVivo = function() {
    return true;
};

var perro = {};
perro.__proto__ = animal;
console.log(perro.toString === Object.prototype.toString);
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/4rVg4/" target="_blank">Pruébame</a></p>
<h3>Como modificar una propidad inaccesible?</h3>
<p>Bien, la teoría ha ido correctamente, pero como ya dijimos, <strong><code>__proto__</code> no es estándar</strong>, y por lo tanto no podemos contar con que funcione en cualquier motor de Javascript, <strong>entonces cómo se supone que vamos a implementar herencia en Javascript?</strong> Para ello Javascript provee de una funcionalidad un tanto difícil de entender así que intentaremos ir poco a poco.</p>
<p><strong>Toda función, creada en Javascript tiene una propiedad llamada <code>.prototype</code> que no debe confundirse con <code>[[Prototype]]</code></strong>, el <code>[[Prototype]]</code> de las funciones apunta a <code>Function.prototype</code> que es un objeto que tiene funciones como <code>.call()</code>, <code>.apply()</code> y <code>.bind()</code>. No, en éste caso nos referimos a que todas las funciones tienen una propiedad llamada <code>prototype</code> que es un objeto vacío. Y porqué se llama <code>prototype</code> si no tiene nada que ver con el <code>[[Prototype]]</code> de la función? <strong>Porque los objetos que creemos llamando a ésa función con <code>new</code> tendrán su <code>[[Prototype]]</code> apuntando a la propiedad <code>prototype</code> de la función:</strong></p>
<pre><code>function myFunct() { }
var obj = new myFunct();
console.log(obj.__proto__ === myFunct.prototype); 
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/r2F8G/" target="_blank">Pruébame</a></p>
<p>Sorpresa! <strong>Hemos modificado la propiedad oculta <code>[[Prototype]]</code> de <code>obj</code>!</strong> Quizás te preguntes porqué no se estandariza la propiedad accesible <code>__proto__</code>? Porque con el sistema de las funciones el lenguaje se asegura que <strong>sólo podemos modificar la propiedad <code>[[Prototype]]</code> de objetos nuevos</strong>, no de existentes. De ésta forma, en las implementaciones estándar donde no podemos acceder a la propiedad <code>__proto__</code> no podemos modificar el prototipo de una función o de <code>Object.prototype</code> ni podemos evitar que un objeto extienda de <code>Object.prototype</code>, poniendo su propiedad <code>__proto__</code> a <code>null</code> romperíamos ésta regla del lenguaje.</p>
<p>Pero <strong>entonces <code>myFunct</code> es una clase? Podría decirse que si, pero no es una clase como las que estamos acostumbrados a ver, es una función, es un objeto y es tangible</strong>, el hecho de crear nuevos objetos con <code>new</code> seguido de una función es solo una sintaxis que se añadió a Javascript para parecerse a Java, lenguaje en plena expansión cuando Javascript fue diseñado. Ahora que entendemos que <code>myFunct.prototype</code> es igual al <code>[[Prototype]]</code> de los objetos que creemos con la función podemos crear objetos que extiendan del mismo objeto:</p>
<pre><code>function myFunct() { }
myFunct.prototype = {
    name: "Alice",
    lastname: "Smith",
    fullname: function() { 
        return this.name + ' ' + this.lastname;
    }
};

var instancia1 = new myFunct();
var instancia2 = new myFunct();

console.log(instancia1.fullname() + '\n' + instancia2.fullname());
console.log(instancia1.__proto__ == instancia2.__proto__); 
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/F2yQy/" target="_blank">Pruébame</a></p>
<p>E incluso podemos crear un objeto que extienda de una instancia de myFunct!</p>
<pre><code>instancia1.name = "Bob";
function extenderInstancia1() { }
extenderInstancia1.prototype = instancia1;
var subInstancia = new extenderInstancia1();

var texto = "Fullname: " + subInstancia.fullname() + '\n';
texto += "Es instancia de extenderInstancia1? " + (subInstancia instanceof extenderInstancia1) + '\n';
texto += "Es instancia de myFunct? " + (subInstancia instanceof myFunct) + '\n';
texto += "Es instancia de Object? " + (subInstancia instanceof Object);

alert(texto); 
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/Ggj6T/" target="_blank">Pruébame</a></p>
<h3><code>extend()</code></h3>
<p>Pero éste lío de tener funciones que parecen clases pero no son clases exactamente y crean instancias y tener que crear funciones para extender es bastante confuso, por ello, los defensores de no mezclar la herencia por prototipos con éstas falsas clases proponen usar la función <code>extend</code>:</p>
<pre><code>function extend(proto) {
    function intermediario() { }
    intermediario.prototype = proto;
    return new intermediario;
}
</code></pre>
<p>Y con ésta función podemos extender objetos sin necesidad de crear funciones intermedias:</p>
<pre><code>var base = {
    name: "Alice",
    lastname: "Smith",
    fullname: function() { 
        return this.name + ' ' + this.lastname;
    }
};

var instancia1 = extend(base);
var instancia2 = extend(base);

instancia1.name = "Bob";
var subInstancia = extend(instancia1);
console.log(subInstancia.fullname()); 
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/WZFAH/" target="_blank">Pruébame</a></p>
<p>Como vemos, el código queda bastante más claro, es por ésto que en la 5ª edición de ECMAScript (el estándar en el que está basado Javascript), se decidió añadir <code>Object.create()</code> que <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/create">cumple la misma funcionalidad</a> que la función <code>extend()</code> que hemos creado.</p>
<h3>Resumen</h3>
<p>Es un camino duro pasar de un lenguaje basado en clases a uno basado en prototipos, requiere mucha práctica, una mente abierta y muchas ganas de aprender. Pero las ganancias son grandes, incluso para desarrolladores que no necesiten tocar Javascript considero que aprender éste patrón aporta ventajas porque <strong>entender ambos patrones en mente nos abre a nuevas ideas, nos ayuda a tener siempre presente que las cosas no tienen porque ser como estamos acostumbrados a que sean, y a buscar nuevas soluciones a nuevos problemas y por último pero no menos importante, nos mantiene activos</strong>. Espero que sea fácil seguir el post aunque se que ha crecido más allá de lo deseado, pido comprensión ya que escribir no es mi punto fuerte, pero para eso está la práctica, para mejorar <img src='http://www.amatiasq.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.amatiasq.com/2012/01/javascript-conceptos-basicos-herencia-por-prototipos/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Javascript Conceptos Básicos: this, .call() y .apply()</title>
		<link>http://www.amatiasq.com/2012/01/javascript-conceptos-basicos-this-call-y-apply/</link>
		<comments>http://www.amatiasq.com/2012/01/javascript-conceptos-basicos-this-call-y-apply/#comments</comments>
		<pubDate>Sun, 08 Jan 2012 19:41:13 +0000</pubDate>
		<dc:creator>amatiasq</dc:creator>
				<category><![CDATA[Conceptos Básicos de Javascript]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[apply]]></category>
		<category><![CDATA[bind]]></category>
		<category><![CDATA[call]]></category>
		<category><![CDATA[conceptos basicos]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[scope]]></category>
		<category><![CDATA[this]]></category>

		<guid isPermaLink="false">http://www.seldaiendil.com/amatiasq/?p=138</guid>
		<description><![CDATA[Antes de continuar con el Patrón Promise me gustaría explicar en paralelo Conceptos Básicos de Javascript. Entendiendo que estamos hablando de Javascript como lenguaje y no vamos a hablar sobre conceptos básicos del DOM o como abrir una nueva ventana en el navegador, sino detalles de Javascript puro, tanto en cliente como en servidor. De [...]]]></description>
				<content:encoded><![CDATA[<p>Antes de continuar con el Patrón Promise me gustaría explicar en paralelo Conceptos Básicos de Javascript. Entendiendo que estamos hablando de Javascript como lenguaje y no vamos a hablar sobre conceptos básicos del DOM o como abrir una nueva ventana en el navegador, sino detalles de Javascript puro, tanto en cliente como en servidor.</p>
<h3>De dónde sale <em>this</em></h3>
<p>He pensado que sería un buen punto empezar por una curiosidad bastante desconocida para los recién llegados a Javascript: La variable <code>this</code>, también llamado el <code>scope</code> o más correctamente <code>contexto</code> de la función. En los lenguajes basados en clases más extendidos (Java, C++, C#&#8230;) encontramos que <strong>los métodos de la clase siempre disponen de la variable <code>this</code> que nos permite acceder a nuestra propia instancia</strong> sobre la que se está ejecutando el método. Es decir, si tenemos la clase</p>
<pre><code>class MyClass {
  String myField;
  void myMethod() {
    this.myField;
  }
}
</code></pre>
<p>Veremos que en myMethod siempre tendremos <code>this</code> apuntando a una variable del tipo <code>MyClass</code> que contendrá un campo <code>myField</code>. En Javascript ésto no es así, <strong>en Javascript todo son objetos</strong>, incluidas las funciones y métodos, ambos <strong>son instancias de <code>Function</code></strong>, y como tales no están ligadas a un objeto en particular. Miremos el código:</p>
<pre><code>function myFunction() {
  console.log(this.name);
}

var objectA = {
  name: "Alice",
  myMethod: myFunction
};

var objectB = {
  name: "Bob",
  myMethod: myFunction
};
</code></pre>
<p>Aquí tenemos dos objetos totalmente independientes y ambos tienen la propiedad <code>myMethod</code> apuntado a <code>myFunction</code> a pesar de que no tienen una clase en común más que <code>Object</code>. Entonces cuál es <strong>el valor de this</strong> en <code>myFunction</code>? No es fijo, <strong>cambia según como lo llamemos</strong>.</p>
<pre><code>objectA.myMethod()
// Imprime "Alice"

objectB.myMethod()
// Imprime "Bob"
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/YUX5B/" target="_blank">Pruébame</a></p>
<p><span id="more-138"></span></p>
<p>Como vemos el valor de <code>this</code> cambia según sobre que objeto lo llamemos. Bien, Javascript sabe que valor tiene que poner a <code>this</code> antes de llamar a una función, pero nosotros necesitamos entenderlo para no encontrarnos con bugs imposibles de corregir. Para ésto hay una regla de oro: <strong>el objeto <code>this</code> pasado a una función es el objeto que está antes del punto que precede los paréntesis que invocan a la función</strong>. Es decir, la llamada <code>objectA.myMethod()</code> la podríamos dividir en cuatro partes:<br />
* <strong>objectA</strong>: El objeto que contiene la función<br />
* **. (punto)**: Separa el objeto de su propiedad (la función)<br />
* <strong>myMethod</strong>: Nombre de la función<br />
* <strong>() (paréntesis)</strong>: Ejecutan la función En éste caso vemos que</p>
<p><strong>antes del punto está <code>objectA</code></strong> por lo que será <code>objectA</code> lo <strong>que se le pasará a la variable <code>this</code></strong> del método <code>myMethod</code>.</p>
<h3>Casos más complejos</h3>
<h4>Más de un punto</h4>
<p>Ahora vamos a ver casos en los que tenemos más o menos de un punto, es menos difícil de lo que parece. Para empezar, que pasa si usamos namespaces:</p>
<pre><code>amq.test.StringHelper.firstToUpperCase('myname');
</code></pre>
<p>Aquí cuál es el valor de <code>this</code>? Si miramos la regla de oro veremos que solo el punto que precede a los paréntesis debe importarnos, por lo que tenemos:</p>
<ul>
<li><strong>amq.test.StringHelper</strong>: El objeto que contiene la función</li>
<li>**. (punto)**: Separa el objeto de su propiedad (la función)</li>
<li><strong>firstToUpperCase</strong>: Nombre de la función</li>
<li><strong>() (paréntesis)</strong>: Ejecutan la función El valor de </li>
</ul>
<p><strong><code>this</code> siempre es el objeto que está antes del último punto</strong>, es decir, el objeto <strong>que contiene la función</strong>.</p>
<h4>Sin puntos</h4>
<p>Pero que pasa si no hay ningún punto? si la función no está en ningún objeto?</p>
<pre><code>function testScope() {
  console.log(this);
}
testScope();
</code></pre>
<p>Aquí podríamos pensar que <code>this</code> es <code>null</code> y tendría sentido pero no, Javascript define que una función invocada sin contexto, el contexto debe ser el Objeto Global, que en el caso de un navegador sería <code>window</code>. Por lo que en <strong>una función que no esté contenida en ningún objeto recibirá el objeto global</strong> como <code>this</code>.</p>
<h3>Callbacks</h3>
<p>Ya con toda ésta base podemos abordar el problema de los callbacks, supongamos que tenemos una función que hace un proceso asíncrono y necesitamos pasarle un callback para que se ejecute cuando el proceso asíncrono termine. Para el ejemplo pondremos que la tarea asíncrona sea esperar un segundo</p>
<pre><code>function esperarUnSegundo(callback) {
  setTimeout(function() {
    callback();
  }, 1000);
}
</code></pre>
<p>Perfecto, ya tenemos una función que espera que pase un segundo y llama al callback, pero que pasa si la usamos de ésta forma?</p>
<pre><code>var alice = {
  nombre: "Alice",
  cansarse: function() {
    alert(this.nombre + " se ha cansado de esperar");
  }
};
esperarUnSegundo(alice.cansarse);
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/erfJF/" target="_blank">Pruébame</a></p>
<p>Aquí tenemos un problema, al parecer <code>this.nombre</code> no es &#8220;Alice&#8221;. Porqué? Repasemos la regla de oro, <code>this</code> será el objeto que está antes del punto que precede a los paréntesis que ejecutan la función. Busquemos los paréntesis que ejecutan la función:</p>
<pre><code>callback();
</code></pre>
<p>Y vemos que no hay ningún punto delante. <strong>La función la hemos extraído del objeto</strong> <code>alice</code>, pero al extraerla la hemos desvinculado de él y al llamarlo ya no se le pasa <code>alice</code> porque ya no se la llama con <code>alice.&lt;nombre del método&gt;</code> Entonces cómo hacemos para que callback no pierda su contexto? para que mantenga el valor de <code>this</code> a <code>alice</code>?</p>
<h3>Los métodos de <code>Function</code></h3>
<p>Para ésto vienen en nuestra ayuda los métodos de <code>Function</code>, como ya dijimos, <strong>las funciones son instancias de la clase <code>Function</code> y como tal tienen también métodos propios</strong>. Los más utilizados son <code>.call()</code> y <code>.apply()</code></p>
<h4><code>.call()</code> Imaginemos que tenemos otra vez el objeto <code>alice</code> y que guardamos su método en una variable.</h4>
<pre><code>var alice = {
  nombre: "Alice",
  cansarse: function() {
    console.log(this.nombre);
  }
};

var myFunction = alice.cansarse;
</code></pre>
<p>Si llamamos a <code>myFunction</code> directamente lo estaríamos llamando sin contexto por lo el la variable <code>this</code> tendría el objeto global dentro de <code>myFunction</code>, como podemos hacer que ejecute <code>myFunction</code> pero pasándole <code>alice</code> como <code>this</code>? Para ésto tenemos las funciones <code>.call()</code> y <code>.apply()</code>, empecemos por la función <code>.call()</code>.</p>
<p><strong>La función <code>.call()</code> recibe los mismos argumentos que la función mas uno, el valor que tendrá <code>this</code> que se pasa antes que los demás argumentos</strong>. Es decir, nuestra función <code>myFunction</code> no recibe ningún argumento así que si llamamos a su método <code>.call()</code> y le pasamos lo que queremos que sea <code>this</code> es decir, <code>alice</code> conseguiremos que el método funcione igual que si lo hubiésemos llamado con <code>alice.cansarse</code></p>
<pre><code>myFunction.call(alice);
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/kbr5t/" target="_blank">Pruébame</a></p>
<p>Ahora vamos a probar lo mismo con una función que reciba argumentos:</p>
<pre><code>var alice = {
  nombre: "Alice",
  saludar: function(amigo1, amigo2) {
    alert("Hola " + amigo1 + " y " + amigo2 + ", yo soy " + this.nombre);
  }
};

var myFunction = alice.saludar;
myFunction.call(alice, "Bob", "Rob");
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/HZuPL/" target="_blank">Pruébame</a></p>
<p>Como se ve, hemos conseguido modificar el valor que tiene <code>this</code> cuando se ejecuta la función, es decir el contexto.</p>
<h4>.apply()</h4>
<p>El método <code>.apply()</code> actúa de forma bastante similar a <code>.call()</code>, pero con una variación, solo <strong>recibe dos argumentos, el primero es el contexto de la función</strong>, el valor de <code>this</code> <strong>y el segundo será un array que contendrá los argumentos que se le pasarán a la función</strong>, veamos su uso en el ejemplo anterior:</p>
<pre><code>myFunction.apply(alice, [ "Bob", "Rob" ]);
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/bSmeR/" target="_blank">Pruébame</a></p>
<p>Esto aunque en un principio parezca bastante inútil nos servirá cuando, queriendo o no cambiar el contexto de una función, <strong>querramos llamarla y no sepamos ni nos interese saber cuántos argumentos tiene</strong>, supongamos que tenemos la función <code>callWithAlice()</code> que llama a la función <code>.saludar()</code> de <code>alice</code> y le pasa todos los argumentos que recibe.</p>
<p><strong>Nota 1:</strong> Para ésto hace falta aclarar que el objeto <code>arguments</code> es una especie de array con los argumentos pasados a la función, más adelante profundizaremos en ello.</p>
<p><strong>Nota 2:</strong> En éste caso no queremos cambiar el contexto, pero como estamos llamando a <code>.apply()</code> tenemos que darle uno, por lo que le damos <code>alice</code> que es el contexto que ya tenía.</p>
<pre><code>function callWithAlice() {
  alice.saludar.apply(alice, arguments);
}
callWithAlice("Rob", "Bob");
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/VrESt/" target="_blank">Pruébame</a></p>
<h4>Bonus: .bind()</h4>
<p>Ahora que ya entendemos el contexto, <code>.call()</code> y <code>.apply()</code> sabremos que cuando pasemos una función como callback si no queremos perder el contexto de la función deberemos hacer:</p>
<pre><code>function esperarUnSegundo(callback) {
  setTimeout(function() {
    callback();
  }, 1000);
});

esperarUnSegundo(function() {
  alice.myMethod();
});
</code></pre>
<p>O bien:</p>
<pre><code>function esperarUnSegundo(callback, context) {
  setTimeout(function() {
    callback.call(context);
  }, 1000);
});

esperarUnSegundo(alice.myMethod, alice);
</code></pre>
<p>Pero ésto puede ser un poco tedioso cuando manejas muchos callbacks de éste tipo, para ello se ha creado el método <code>.bind()</code>. Es un método de <code>Function</code> que devuelve otra función. Confuso, verdad?</p>
<p><strong><code>.bind()</code> recibe un argumento, el contexto que se le podrá a la función sobre la que se aplica el <code>.bind()</code> y devolverá una función</strong> que cuando sea llamada ejecutará la función original con el contexto que se le pasó a <code>.bind()</code>. Lo veremos mejor con un ejemplo:</p>
<pre><code>var alice = {
  nombre: "Alice",
  saludar: function() {
    console.log("Hola! Soy " + this.nombre);
  }
};

var myFunction = alice.saludar.bind(alice);
myFunction();
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/NUWCy/" target="_blank">Pruébame</a></p>
<p>Lo que hemos hecho en la línea 8 es crear una función que cuando sea invocada llamará a <code>saludar</code> y le pasará <code>alice</code> como contexto.</p>
<h3>Y ya está!</h3>
<p>Con éste repaso ya deberíamos ser capaces de entender la parte más complicada para un recién llegado a Javascript, la modificación del contexto. Es una técnica que requiere mucha práctica, pero detrás de la cual se esconde la mitad del potencial de Javascript y como tal, también nos abre los ojos a muchos bugs que de otra forma serían imposibles de entender.</p>
<p>De hecho, para los que les gusta romperse la cabeza como yo, les dejo un caramelo: Todas las funciones tienen los métodos <code>.call()</code>, <code>.apply()</code> y <code>.bind()</code>, es cierto. Pero éstos métodos también son funciones, eso significa que podemos hacer ésto? Que resultado tendría? Se los dejo a ustedes <img src='http://www.amatiasq.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<pre><code>alice.saludar.call.call.call.call.apply.bind()
</code></pre>
<p>Y que pasa si llamo a uno de éstos métodos y no le paso scope?</p>
<pre><code>alice.saludar.call(null);
</code></pre>
<p>Espero que haya sido claro y conciso, pero me temo que ha sido más de lo primero que de lo segundo. Pronto tendré otro artículo sobre Conceptos Básicos de Javascript. Saludos.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.amatiasq.com/2012/01/javascript-conceptos-basicos-this-call-y-apply/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Patrón Promise: Implementación (I)</title>
		<link>http://www.amatiasq.com/2011/12/patron-promise-implementacion-i/</link>
		<comments>http://www.amatiasq.com/2011/12/patron-promise-implementacion-i/#comments</comments>
		<pubDate>Sun, 18 Dec 2011 22:56:50 +0000</pubDate>
		<dc:creator>amatiasq</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Promise]]></category>

		<guid isPermaLink="false">http://www.seldaiendil.com/amatiasq/?p=68</guid>
		<description><![CDATA[Lo prometido es deuda (bien lo saben las funciones) y he encontrado un momento para empezar a explicar la forma en la que he implementado el patrón Promise en mi caso, no tiene porqué ser la mejor, pero cumple con su cometido. NOTA: Me gustaría implementarla en Test Driven Development, pero ya es bastante para [...]]]></description>
				<content:encoded><![CDATA[<p>Lo prometido es deuda (bien lo saben las funciones) y he encontrado un momento para empezar a explicar la forma en la que he implementado el patrón Promise en mi caso, no tiene porqué ser la mejor, pero cumple con su cometido.</p>
<p><strong>NOTA:</strong> Me gustaría implementarla en Test Driven Development, pero ya es bastante para quien lee y para el que escribe seguir la implementación como para encima añadir TDD, pero no quisiera dejar de recomendarlo.</p>
<h3>Primero: Funcionalidad básica</h3>
<p>Lo que necesitamos de un objeto Promise es:</p>
<ul>
<li>Crear instancias totalmente independientes</li>
<li>Añadirle callbacks que serán llamados cuando se cumpla la promesa</li>
<li>Notificarle cuando se ha cumplido la promesa</li>
</ul>
<p><span id="more-68"></span></p>
<p>Con los objetivos en la mano es más sencillo ver que hacer, lo primero necesitamos una clase, a la hora de crear clases en Javascript yo me decanto por el patrón de constructor con prototipos que espero explicar algún día.</p>
<pre><code>function Promise() { }
</code></pre>
<p><strong>Segundo punto:</strong> poder añadirle callbacks, ésto consiste en el método <code>.then()</code> al que deberemos poder llamar pasándole las funciones que queremos que se ejecuten cuando la promesa se cumpla. Puesto de debe poderse añadir más de un callback para cada promise lo más lógico sería crear un Array donde almacenarlos</p>
<pre><code>function Promise() {
  this._callbacks = [];
}
</code></pre>
<p>Y el método <code>.then()</code> que vaya añadiendo al Array los callbacks que se le pasen, puesto que es mejor que los errores se detecten cuanto antes también podemos asegurarnos que el callback es una función:</p>
<pre><code>Promise.prototype.then = function(callback)  {
  if (typeof callback !== 'function') {
    throw new Error("[Promise.then] El argumento 'callback' no es una función " + typeof callback);
  }

  this._callbacks.push(callback);
};
</code></pre>
<p>Y ahora que ya tenemos todos los callbacks en un Array necesitamos algún sistema para avisarle al Promise que ya tiene los datos que necesita y que se los pase a los callbacks. Sobre ésto no he visto ninguna implementación, pero a mi me parece bastante razonable crear un método <code>Promise.done()</code> que notifica al Promise que ya está cumplido y ejecuta los callbacks.</p>
<pre><code>Promise.prototype.done = function() {
  var callback;
  for (var i = 0; i &lt; this._callbacks.length; i++) {
    callback = this._callbacks[i];
    callback();
  }
};
</code></pre>
<p>Y ya lo tenemos hecho, hemos creado un Promise básico, vamos a probarlo. Imaginemos cualquier función asíncrona, por ejemplo vamos a crear una función que nos avise cuando pase un segundo:</p>
<pre><code>function esperarUnSegundo() {
  var promise = new Promise();
  // Hacemos un timeout a mil milisegundos
  setTimeout(function() {
    promise.done();
  }, 1000);
  return promise;
}

esperarUnSegundo().then(function() {
  alert("Ha pasado un segundo =D");
});
</code></pre>
<p><a href="http://jsfiddle.net/amatiasq/4LBWd/2/" target="_blank">Pruébame</a></p>
<p>Si probamos todo el código veremos que al cabo de un segundo ejecuta el alert.</p>
<p>Todo funciona perfectamente, vamos un punto más allá, ésta vez descarguemos una página, como no nos importa ahora mismo el código que descarga la página fingiremos llamar a una función <code>peticiónHttp(url, callback)</code> que lo hará por nosotros.</p>
<pre><code>function descargar(url) {
  var promise = new Promise();
  peticiónHttp(url, function(codigoHtml) {
    promise.done();
  });
  return promise;
}
descargar('www.google.com').then(function() {
  // Y ahora?
});
</code></pre>
<p>Sorpresa! La función ha descargado la página y obtenido el html, pero nuestro Promise no ha sido capaz de pasarlo al callback. La función del Promise en un principio era avisar cuando una tarea asíncrona termina, pero la mayoría de las tareas asíncronas devuelven un resultado y cuando avisemos al Promise que se ha cumplido también querremos que pase el resultado a todos los callbacks. Para ello modificaremos el método done y para que pase a los callbacks todos los argumentos que se le pasen a él (si no sabes lo que hace el método apply puedes mirarlo <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply" title="appy method">aquí</a>):</p>
<pre><code>Promise.prototype.done = function() {
  // Guardamos los argumentos que se le ha pasado a .done()
  var args = arguments;
  var callback;
  for (var i = 0; i &lt; this._callbacks.length; i++) {
    callback = this._callbacks[i];
    // Y se los pasamos al callback
    callback.apply(null, args);
  }
};
</code></pre>
<p>Y ya está, ahora podemos pasarle argumentos a <code>.done()</code>:</p>
<pre><code>function descargar(url) {
  var promise = new Promise();
  peticiónHttp(url, function(codigoHtml) {
    promise.done(codigoHtml);
  });
  return promise;
}

descargar('www.google.com').then(function(codigoHtml) {
  alert(codigoHtml);
});
</code></pre>
<p>Ya tenemos nuestra versión 0.1 de la clase Promise <img src='http://www.amatiasq.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<h3>Segundo: Gestión de errores</h3>
<p>Hasta aquí ya tenemos un Promise con el que avisar cuando acaba una tarea asíncrona, pero nos olvidamos de algo muy importante, a la hora de programar no todo sale como quisiéramos y muchas veces nos encontramos con errores, que pasaría si <code>peticiónHttp()</code> fallara? Que jamás se ejecutaría el <code>.done()</code> del Promise que hemos devuelto y el callback esperará sentado a que lo llamen el resto de su vida. Hay que preparar el Promise para que avise cuando algo va mal. Necesitamos añadirle al Promise:</p>
<ul>
<li>Poder añadir callbacks especiales para cuando se produzca un error</li>
<li>Avisarle cuando se produzca un error</li>
<li>Que le pase al callback de error el objeto Error que se ha lanzado</li>
</ul>
<p>Lo primero es que el Promise no solo reciba un callback normal sino que también reciba otro callback que será ejecutado solo si se produce un error. Una idea que me gusta es dárselo al método <code>.then()</code> como segundo argumento, ya que el primero es el callback normal. Y éste debería guardarlo, para ello debemos crear otro Array donde guardar los callbacks de errores:</p>
<pre><code>function Promise() {
  this._callbacks = [];
  this._onError = [];
}
Promise.prototype.then = function(callback, onError) {
  // Validamos el callback normal
  if (typeof callback !== 'function') {
    throw new Error("[Promise.then] El argumento 'callback' no es una función " + typeof callback);
  }
  // Validamos el callback de error. Como es opcional puede ser 'undefined' o una función
  if (onError &amp;&amp; typeof onError !== 'function') {
    throw new Error("[Promise.then] El argumento 'onError' no es una función " + typeof onError);
  }

  this._callbacks.push(callback);
  // Si no era undefined debe ser una función, porque ya lo validamos
  if (onError) {
    this.\_onError.push(onError);
  }
};
</code></pre>
<p>Como se ve es prácticamente lo mismo que para los callbacks, ya que se trata de lo mismo, un callback por si hay errores. Ahora vamos a matar los últimos dos puntos de un tiro. Añadiremos un método para avisar al Promise cuando se produzca un error y le pasaremos el objeto Error para que lo pase a todos los callbacks de error.</p>
<pre><code>Promise.prototype.fail = function(error) {
  var callback;
  for (var i = 0; i &lt; this._onError.length; i++) {
    callback = this._onError[i];
    callback(error);
  }
};
</code></pre>
<p>Y ya está, ahora cuando llamemos al método <code>.fail()</code> llamará a todos los callbacks de error y les pasará el objeto Error. Ahora podemos adaptar la función <code>descargar()</code> para que también notifique cuando se produzca un error:</p>
<pre><code>function descargar(url) {
  var promise = new Promise();
  try {
    peticiónHttp(url, function(codigoHtml) {
      promise.done(codigoHtml);
    })
  } catch (error) {
    promise.fail(error);
  }
  return promise;
}
descargar('www.google.com').then(function(codigoHtml) {
  alert(codigoHtml);
});
</code></pre>
<p>Ahora ya podemos decir que tenemos la versión 0.2 del Promise tengo que dejar para otro post métodos más complicados como <code>.then()</code> concatenados y el <code>.and()</code> porque ya es muy tarde. Aquí dejo el código completo al que le he añadido la propiedad <code>_estado</code> para evitar que se pueda cumplir o fallar un Promise cuando ya está cumplido o fallado.</p>
<pre><code>function Promise() {
  this._callbacks = [];
  this._onError = [];
  this._estado = "esperando";
}

Promise.prototype.then = function(callback, onError) {
  // Validamos el callback normal
  if (typeof callback !== 'function')
    throw new Error("[Promise.then] El argumento 'callback' no es una función " + typeof callback);

  // Validamos el callback de error. Como es opcional puede ser 'undefined' o una función
  if (onError &amp;&amp; typeof onError !== 'function')
    throw new Error("[Promise.then] El argumento 'onError' no es una función " + typeof onError);

  this._callbacks.push(callback);
  // Si no era undefined debe ser una función, porque ya lo validamos
  if (onError) 
    this._onError.push(onError);
};

Promise.prototype.done = function(error) {
  if (this._estado !== 'esperando')
    throw new Error('Intentando cumplir un promise que ya ha finalizado');

  this._estado = "cumplido";
  // Guardamos los argumentos que se le ha pasado a .done()
  var args = arguments;
  var callback;

  for (var i = 0; i &lt; this._callbacks.length; i++) {
    callback = this._callbacks[i];
    // Y se los pasamos al callback
    callback.apply(null, args);
  }
};

Promise.prototype.fail = function(error) {
  if (this._estado !== 'esperando') throw new Error('Intentando hacer fallar un promise que ya ha finalizado');

  this._estado = "fallado";
  var callback;

  for (var i = 0; i &lt; this._onError.length; i++) {
    callback = this._onError[i];
    callback(error);
  }
};
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.amatiasq.com/2011/12/patron-promise-implementacion-i/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>El patrón Promise</title>
		<link>http://www.amatiasq.com/2011/12/el-patron-promise/</link>
		<comments>http://www.amatiasq.com/2011/12/el-patron-promise/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 16:38:26 +0000</pubDate>
		<dc:creator>amatiasq</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Patrones]]></category>
		<category><![CDATA[Promise]]></category>

		<guid isPermaLink="false">http://www.seldaiendil.com/amatiasq/?p=17</guid>
		<description><![CDATA[PROBLEMA Recientemente he tenido que implementar un sistema MVC en Javascript para simplificar el desarrollo sobre una plataforma y me he encontrado con el problema de que las llamadas asíncronas a servidor rompían la simpleza del código, tras un análisis identifiqué cuatro problemas: 1 &#8211; Ensuciar la API Todas las llamadas reciben un último argumento [...]]]></description>
				<content:encoded><![CDATA[<h2>PROBLEMA</h2>
<p>Recientemente he tenido que implementar un sistema MVC en Javascript para simplificar el desarrollo sobre una plataforma y me he encontrado con el problema de que las llamadas asíncronas a servidor rompían la simpleza del código, tras un análisis identifiqué cuatro problemas:</p>
<h4>1 &#8211; Ensuciar la API</h4>
<p>Todas las llamadas reciben un último argumento que es el callback:</p>
<pre><code>var dir = new Directory('file:///home/user/Desktop');
dir.browse(function(dir, items) {
  // ...
});
</code></pre>
<p>Con ésto la API resulta confusa desde el punto de vista de la simpleza y de la semántica. Semánticamente una función recibe la información mínima indispensable para devolver un dato relacionado a lo que se le ha solicitado, como vemos no es el caso en métodos asíncronos:</p>
<pre><code>void Directory.browse(Function callback);
void File.getContent(String encoding, Function callback);
void File.getPermission(Function callback);
</code></pre>
<p><span id="more-17"></span></p>
<h3>2 &#8211; Llamadas anidadas</h3>
<p>En muchas ocaciones deberemos ejecutar una llamada al acabar otra, ésto nos obliga a anidar callbacks:</p>
<pre><code>var file = new File();
file.isReadable(function(permission) {
  if (permission) {
    file.getContent(function(content) {
      // do something with the content
    });
  }
});
</code></pre>
<p>A medida que vamos añadiendo niveles de profundidad ésto se vuelve muy confuso.</p>
<h3>3 &#8211; Llamadas concurrentes</h3>
<p>También necesitaremos realizar llamadas asíncronas paralelas y ejecutar una acción al acabar todas:</p>
<pre><code>var isFile1Done = false;
var isFile2Done = false;

function testIsOver() {
  if (isFile1Done &amp;&amp; isFile2Done) {
    // Both files loaded.
  }
}

File.get('http://www.somedomain.com/file1', function() {
  isFile1Done = true;
  testIsOVer();
});
File.get('http://www.somedomain.com/file2', function() {
  isFile2Done = true;
  testIsOVer();
});
</code></pre>
<p>Como podemos ver algo tan sencillo como dos peticiones paralelas necesitan mucho código para manejarlas.</p>
<h3>4 &#8211; Gestión de errores</h3>
<p>Es traumática la forma de gestionar errores mediante callbacks, el método más extendido que he visto ha sido el de nodejs, el primer argumento de cada callback es el objeto Error si es que hubo alguna excepción, lo que me parece horrible ya que cada función debe confirmar que su primer argumento es <code>undefined</code> para asegurar que no han habido errores:</p>
<pre><code>File.get('http://www.somedomain.com/file2', function(error, file) {
  if (error) {
    // Show blue screen of death
  }
  // do something with file.
});
</code></pre>
<h2>SOLUCION</h2>
<p>Queda claro que las peticiones asíncronas son necesarias en cliente y servidor ya que permiten al programa continuar trabajando mientras espera la respuesta a la petición, pero éstos problemas podrían dificultar la manutención del código. Y aquí es donde viene a ayudarnos el Patrón Promise. El patrón Promise asiste a una función que no puede devolver inmediatamente su resultado (es decir, una función asíncrona) y devuelve la promesa de que tendrá el resultado en un futuro (a lo que llamo cumplir la promesa <img src='http://www.amatiasq.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> ). A nivel de implementación, una función devuelve un objeto <strong>Promise</strong> que gestionará por ella el callback. Veamos cómo soluciona nuestros problemas:</p>
<h4>1 &#8211; Claridad en los métodos</h4>
<p>La función solo debe recibir la información necesaria para hacer la petición y devuelve la promesa de que esos datos llegarán.</p>
<pre><code>var dir = new Directory('file:///home/user/Desktop');
var promise = dir.browse();
promise.then(function(dir, items) {
  // ...
});
</code></pre>
<p>Y ésto aún lo podríamos mejorar llamando directamente a la función then sin guardar el promise en una variable:</p>
<pre><code>var dir = new Directory('file:///home/user/Desktop');
dir.browse().then(function(dir, items) {
  // ...
});
</code></pre>
<p>Y muchos dirán ¿qué diferencia hay entre ésto y el código que teníamos antes? Es sencillo, la diferencia está en quién maneja el callback. Con el código anterior cada función debía encargarse de comprobar si se le había pasado un callback válido y llamarlo al acabar su tarea con los argumentos necesarios. Ahora todo ése código está en la clase <code>Promise</code> y la función puede encargarse de aquello que le corresponde siempre que devuelva un promise y le notifique cuando termine. Finalmente la API queda bastante más clara:</p>
<pre><code>Promise&lt;Array&lt;File&gt;&gt; Directory.browse();
Promise&lt;String&gt; File.getContent(String encoding);
Promise&lt;Boolean&gt; File.getPermission();
</code></pre>
<h3>2 &#8211; Llamadas secuenciales</h3>
<p>El promise trae una sorpresa que no me esperaba, el método <code>then</code> de la clase <code>Promise</code> devuelve un nuevo <code>promise</code>. Para qué? para poder ejecutar código secuencialmente, veamoslo:</p>
<pre><code>var file = new File();
file.isReadable()
  .then(function(permission) {
    if (permission) {
      return file.getContent();
    }
})
.then(function(content) {
  // do something with the content
});
</code></pre>
<p>Qué es ésta locura? La idea es muy sencilla, pero es confusa porque la explicación utiliza demasiadas veces la palabra <code>Promise</code>, primero expandiremos el código para verlo más claro:</p>
<pre><code>var file = new File();
var promise1 = file.isReadable();

var promise2 = promise1.then(function(permission) {
  if (permission) {
    var promise3 = file.getContent();
    return promise3;
  }
});

promise2.then(function(content) {
  // do something with the content
});
</code></pre>
<p>Debemos intentar seguirlo poco a poco, la llamada a llamada <code>file.isReadable()</code> nos devuelve <code>promise1</code>, y cuando llamamos al método then de <code>promise1</code> nos devuelve <code>promise2</code>. Cuando <code>promise1</code> termina se ejecuta el callback pasado y se descubre que el callback devuelve un nuevo <code>Promise</code>, <code>promise3</code>. Cuando <code>promise3</code> se cumpla (es decir pase a estado &#8220;done&#8221;) también se cumplirá el <code>promise2</code> ejecutando el callback que le han pasado. En resumen, podemos seguir añadiendo callbacks que se ejecutarán al acabar el anterior encadenando llamadas a then.</p>
<h3>3 &#8211; Llamadas paralelas</h3>
<p>Además me planteé añadir la posibilidad de manejar llamadas paralelas desde <code>Promise</code>, puesto que ya hemos visto lo complejo que puede ser. Para ésto añadí el método <code>and</code> al Promise:</p>
<pre><code>File.get('http://www.somedomain.com/file1')
  .and(File.get('http://www.somedomain.com/file2'))
  .then(function() {
    // Both files loaded.
  });
</code></pre>
<p>Una vez más expandamos el código para ver más claramente que está sucediendo:</p>
<pre><code>var promise1 = File.get('http://www.somedomain.com/file1');
var promise2 = File.get('http://www.somedomain.com/file2');
var promise3 = promise1.and(promise2);
promise3.then(function() {
  // Both files loaded.
});
</code></pre>
<p>Al expandirlo es más fácil ver lo que sucede, todo <code>Promise</code> tiene un método <code>and</code> al que se le pasa otro <code>Promise</code>, y ésto devuelve un nuevo <code>Promise</code> que se cumplirá cuando los dos primeros estén cumplidos.</p>
<h3>4 &#8211; Callbacks específicos</h3>
<p>Finalmente el patrón Promise también trae una mejora al problema de la gestión de errores, aún no lo he mencionado pero el método <code>then</code> recibe dos argumentos: el primero el callback que será llamado cuando el Promise se cumpla, el segundo otro callback que será llamado si la ejecución asíncrona falla:</p>
<pre><code>File.get('http://www.somedomain.com/file2').then(function(file) {
  // do something with file.
}, function(error) {
  // Show blue screen of death
});
</code></pre>
<p>Esto nos permite separar claramente la responsabilidad de cada función y nos libera de la carga de comprobar errores.</p>
<h2>CONCLUSION</h2>
<p>Como vemos las llamadas secuenciales traen muchos inconvenientes, pero son principalmente consecuencias de no estar acostumbrados a la programación asíncrona, si lo estuviéramos tendríamos más en mente patrones como Promise que como vemos nos ayuda a afrontar una programación que ya de por sí es complicada. En próximos posts espero mostrar paso la implementación de una clase Promise, nos vemos en la próxima.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.amatiasq.com/2011/12/el-patron-promise/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
