Tuesday, September 23, 2014

¿Cómo funciona this en JavaScript?

En JavaScript, comprender el funcionamiento de this en las llamadas a funciones no suele ser sencillo al principio. Sin embargo, si se entiende lo que internamente hace JavaScript en las llamadas a funciones, todo queda más claro:

Cuando se llama a una función:

foo('hola')

internamente es como si se hiciera lo siguiente:

foo.call(undefined/window, 'hola');

Por otro lado, si se llama a una función perteneciente a un objeto:

objeto.foo('hola')

internamente es como si se hiciera lo siguiente:

foo.call(objeto, 'hola');

El primer parámetro de call es el valor de this dentro de la función. En modo estricto (strict mode), el valor pasado como this será undefined, mientras que en modo no estricto, será el objeto global (objeto window en cualquier navegador).

Teniendo esto en cuenta, veamos lo que pasaría con un objeto como el siguiente:

var person = {
    firstName: 'Isidro',
    sayHello: function() {
        console.log("Hello, I'm "+this.firstName);
    }
}

Si hacemos:

    person.sayHello();

Por consola se mostrará "Hello, I'm Isidro". En este caso, internamente se ejecuta algo como:

    person.sayHello.call(person);
   
Por lo que this.firstName "sería" person.firstName

¿Qué pasaría si obtengo una referencia a la función del objeto y la llamo desde fuera en modo no estricto?

var f = person.sayHello;
f();

En este caso, por consola se pintará "Hello, I'm undefined"

Esto es porque internamente se ejecuta algo como:

    person.sayHello.call(window);
   
y por tanto, como en el objeto window no hay ningún objeto llamado firstName, muestra undefined.   

En este caso, si quisiéramos ligar la función con un objeto en particular, usaríamos bind:

    f = person.sayHello.bind(person);
   
Ahora al ejecutar la función devolvería:   

    f(); // Hello, I'm Isidro
   
¿Qué pasa con las funciones anónimas?

Supongamos que la clase person es ahora:

var person = {
    firstName: 'Isidro',
    sayHello: function() {
        function getCapitalizeName() {
            return this.firstName.toUpperCase();
        }
        console.log("Hello, I'm "+getCapitalizeName());
    }
}

y ejecutamos:

    person.sayHello();   
   
En este caso, se muestro por consola de nuevo: "Hello, I'm undefined"
El motivo se entiende claramente si traducimos la llamada a la función getCapitalizeName() por lo que realmente se está ejecutando:

    getCapitalizeName.call(window)

De nuevo, dentro de getCapitalizeName, this apuntará a window y como en el objeto window no existe el objeto firstName, devuelve undefined. No podemos pensar que como la función getCapitalizeName está definida dentro del objeto person, automáticamente this apunta a person.

Para que funcione tal como esperamos, podríamos llamar a la función getCapitalizedName de forma explícita:

    console.log("Hello, I'm "+getCapitalizeName.call(this));  

En este caso, mostraría: Hello, I'm ISIDRO

Saturday, August 9, 2014

Herencia Prototípica y AngularJS

A veces, aquellos que vienen de lenguajes con herencia clásica como Java, se encuentran con serios problemas cuando empiezan a trabajar con otros tipos de herencia como la prototípica de Javascript (Prototypal Inheritance). 

Un ejemplo es cuando se trabaja con AngularJS y se usan directivas que crean scopes que heredan prototípicamente de su scope padre, en concreto, directivas como ng-include, ng-switch, ng-controller o directivas con scope:true. En estos casos, el desarrollo puede generar dolores de cabeza si no se entiende bien este tipo de herencia.

Veamos un ejemplo. Supongamos que tenemos una directiva como la siguiente:

directive('test', [function() {
    return {
     scope: true,
     template: '<input type="checkbox" ng-model="active"></input>'
    };
}])

En este caso, la directiva crea un nuevo scope que hereda prototípicamente del scope padre.

Supongamos que tenemos un sencillo controlador como el siguiente:

controller('TestCtrl', ['$scope', function($scope) {
$scope.active=true;
}]);

Si nuestro template es el siguiente:

<div ng-controller="TestCtrl">
<div test1></div>{{active}}
</div>

Vemos que cuando ejecutamos la aplicación, aparece el checkbox marcado y bajo él la palabra true como era de esperar, ya que en el controlador la variable active se inicia a true.

Hasta aquí todo bien. Pero, ¿qué pasa cuando desmarcamos el checkbox?  ¡Sigue apareciendo true debajo del checkbox!

¿No debería cambiar la vista adaptándose al valor actual? Pues sí, pero aquí entra en juego la herencia prototípica que complica un poco las cosas.

La herencia prototípica tiene la siguiente peculiaridad: para leer siempre se recorre la cadena de prototipos hacia arriba hasta encontrar la variable, mientras que para escribir no se recorre, por el contrario, se escribe en el objeto (scope) actual.

Lo que realmente está pasando es que tenemos dos scopes, uno el del controlador (S1) y otro el de la directiva (S2) que hereda prototípicamente de S1:

S1, que es el scope asociado al controlador (TestCtrl), incluye la variable active=true.
S2, que es el scope asociado a la directiva, no incluye esa variable.

Cuando se ejecuta la aplicación, la directiva enlaza el valor del checkbox con la variable active del scope. Pero, ¿de qué scope? pues del scope de la directiva. En este caso, intenta leer el valor de la variable active en el scope S2. Como en este scope no está definida, siguiendo las reglas de la herencia prototípica, busca en el scope padre S1 donde sí se encuentra y se muestra el checkbox marcado. Por otro lado, en la vista se muestra true porque ésta va enlazada con el scope S1 del controlador.

Cuando desmarcamos el check, lo que se está haciendo es una escritura. De nuevo, se comienza por el scope de la directiva S2. Como antes, en este scope no se encuentra la variable active y, aquí surge la confusión, se crea una nueva variable active con el estado false en S2.

En este momento hay definidas dos variables active, una en S1 con el valor true y otra en S2 con el valor false. La nueva variable active de S2 es la que a partir de ahora estará asociada al checkbox y la S1 seguirá asociada al controlador (vista). Es por ello, que en la vista aparece true ya que realmente la variable que se está leyendo para formar la vista es la de S1.

Si volviéramos a marcar el checkbox, el proceso sería el mismo, quedando en este caso la variable active de S2 con valor true, el checkbox marcado y en la vista la palabra true proveniente de la variable active del scope S1.

Una forma para evitar este tipo de problemas es usar variables accedidas por referencia en vez de por valor. Pero esto lo veremos en otro post otro día.

Wednesday, August 6, 2014

Java implementation of the Travesty algorithm

Some days ago I wrote a Java implementation of the Travesty algorithm using a probability tree structure.

Travesty is a method for generating scrambled text using Markov chains.

This is a free interpretation of the Travesty algorithm by Hugh Kenner and Joseph O'Rourke discussed in BYTE November 1984 (www.scribd.com/doc/99613420/Travesty-in-Byte) based on the paper "Richard A. O’Keefe - An introduction to Hidden Markov Models".

As this paper (www.cs.otago.ac.nz/cosc348/hmm/hmm.pdf) says:

"A kth-order travesty generator keeps a “left context” of k symbols.

Here k = 3, one context is “fro”. At each step, we find all the places in the text that have the same left context, pick one of them at random, emit the character we find there, and shift the context one place to the left. For example, the text contains “(fro)m”, so we emit “m” and shift the context to “rom”. The text contains “p(rom)ise”, so we emit “i” and shift the context to “omi”. The text contains “n(omi)nation”, so we emit “n” and shift the context to “min”. The text contains “(min)e”, so we emit “e” and shift the context to “ine”. And so we end up with “fromine
”.

How is this a Markov chain? The states are (k + 1)-tuples of characters, only those substrings that actually occur in our training text. By looking at the output we can see what each state was. There is a transition from state s to state t if and only if the last k symbols of s are the same as the first k symbols of t, and the probability is proportional to the number of times t occurs in the training text.

A Travesty generator can never generate any (local) combination it has not seen; it cannot generalise"

As an example, using the first paragraph of "El Quijote" (in spanish) and k=3, the outcome are things as curious as the following:

"... de Quijada (que en su hay amigo de asta años, en la conjeturas más velludo parte, carnes, en los cincuentejas cuyo no que vierencia, duelos de caza. El recia, y una sobrina sobrina se de llero, algún para la narraciender que tenía el sobre semana que en la Mancha, y un punto; gran lugador y galga años, era. El rocín flaco y un hidalgún punto; gran mozo de cuyo no hay amigo de verdad ..."

As you can observe, the text is scrambled although it looks like a text with valid spelling and grammar.

You can download the source code from my GitHub: https://github.com/IsidroGH/Travesty

Tuesday, April 15, 2014

Peticiones HTTP asíncronas con AngularJS

Esta es una forma de hacer peticiones Get asíncronas con AngularJS:

angular.module('TestApp').
controller('MainCtrl', ['Async', function (Async) {     
  Async.get(<URL>).then(
      function(data) {
          console.log("OK:",data);
      }, function(error) {
          console.log("ERROR:", error);
      });
}]).
// Servicio que encapsula operaciones asíncronas
factory('Async', ['$http', function($http) {     
  return {
      get: function(url) {
        var promise = $http.get(url).then(function (response) {
          // Devuelvo el body
          return response.data;
        });
           
        return promise;
      }
  };
}]);


He creado un servicio llamado Async con una función "get" que devuelve un objeto "promise". Este objeto promise es consumido de forma habitual por el llamante, en este caso un controlador llamado "MainCtrl"

Si la respuesta es correcta, se devuelve al controlador el body del mensaje http. En el caso particular que el body sea una cadena JSON, Angular la convierte automáticamente a un objeto.

Si la llamada acaba en error, se devuelve al controlador el objeto de error con el status y el mensaje de error, entre otra información.

Tuesday, April 8, 2014

Javascript prototypal inheritance with Object.create


An advantage that can turns out in disadvantage is that Javascript is a very expressive language. You can do something in very different ways. In this case I'll show a way to model inheritance using Object.create (ECMAScript 5).

In the following example, two objects are created: parent and child. These both objects are like "classes" in lenguajes with classical inheritance as Java. From those objects, I create two instances using Object.create: Pepe (the parent) and Pablo (the child). In this case, Pablo prototypically inherits from Pepe.


// In case of using IE 
if (typeof console === 'undefined') {
  console = {
  log: function(text) {
  alert(text);
  }
  }
}
    
// In case of using IE<10
if(typeof Object.create !== 'function') { 
  Object.create = function (o) { 
    function F() {}; 
    F.prototype = o; 
    return new F(); 
  }; 
}
    
// Helper to add properties to an object
function extend(obj, props) { 
  for(prop in props) { 
    if(props.hasOwnProperty(prop)) { 
      obj[prop] = props[prop]; 
    } 
  } 
}
    
    // Parent object
var parent = {
talk: function() {
console.log("I'm "+this.name);
},
work: function() {
console.log("I'm going to work");
},
init: function(name) {
this.name=name;
return this;
},
create: function(name) {
return Object.create(this).init(name);
}
};

// Child object
var child = Object.create(parent)
extend(child, {
work : function() {
    console.log("I can't work, I'm a child!");
}
});

// Parent instance
var pepe = parent.create("Pepe");

// Child instance
var pablo = child.create("Pablo");

pepe.talk(); // I'm Pepe
pepe.work(); // I'm going to work

pablo.talk(); // I'm Pablo
pablo.work(); // I can't work, I'm a child!


Monday, January 20, 2014

I2Talentia - Ya estamos en fase de pruebas

Ya por fin tenemos una versión beta de la plataforma I2Talentia, nuestra innovadora plataforma de aprendizaje adaptativo.

Si quieres ser  betatester solicita tu código en info@i2talentia.com

Próximamente la abriremos para el público.

¡Esperamos que os sea de utilidad!

Monday, January 6, 2014

Cómo una maleta fea hace vender más


Hace unos meses fui a comprar una maleta a un centro comercial. Me mostraron un nuevo modelo de una marca que todo el mundo conoce. Este modelo estaba disponible en dos colores y curiosamente a dos precios distintos. Por un lado estaba el modelo negro digamos a 100€ y el modelo azul  a 60€. Realmente la maleta en color negro era bastante bonita al contrario que la azul que, aún siendo el mismo modelo, resultaba algo fea.

Me resultó curioso la diferencia de precio porque se trataba de un modelo nuevo. Es normal que para liquidar restos de productos se bajen los precios, pero en este caso no me cuadraba.

¿Por qué ponen la misma maleta con colores distintos pero con los mismos costes de producción, a precios distintos?

No tengo certeza del motivo aunque puedo intuir un motivo. Podemos hacer un pequeño ejercicio (muy simplista):

Supongamos que existen dos tipos de personas, un tipo con presupuesto holgado (PH) y otra con presupuesto limitado (PL). ¿Cuál sería la facturación jugando con los distintos precios de las maletas?

Negra 100€, Azul 100€
En este caso, la persona con presupuesto holgado compraría la negra. Sin embargo, la persona con presupuesto limitado seguramente comprara una maleta de otra marca más económica.

Facturación = 1N*100€ + 0A*100€ = 100€

Negra 60€, Azul 60€
En este caso, ambas personas comprarían la negra que claramente es más bonita.

Facturación = 1N*60€ + 1A*60€ = 120€

Negra 100€, Azul 60€
En este caso, que es el real, la persona con presupuesto holgado compraría la negra. Sin embargo, la persona con presupuesto limitado posiblemente comprara la azul ya que preferiría sacrificar el aspecto visual a favor de la calidad y prestigio de la marca.

Facturación = 1N*100€ + 1A*60€ = 160€

Vemos como en este último caso se maximizan los beneficios.

La moraleja de todo esto es que a veces interesa complementar un modelo "bonito" con un modelo más "feo" pero más barato para que personas con menos presupuesto compren y, además, asegurar que las personas que pueden gastar más sigan comprando el modelo más caro.

¿No os ha pasado nunca ir a comprar una camiseta y resulta que la que más os gusta, que encima está a buen precio, le han puesto un estampado, dibujo, o algo por el estilo que la hace más fea? y, os preguntáis "¿Para qué le habrán puesto esto? Si no se lo hubieran puesto estaría más bonita".

Bueno, pues posiblemente para que si tenéis presupuesto holgado os compréis la otra camiseta que está al lado que no tiene ningún estampado pero es más cara.




Thursday, January 2, 2014

Simplifying graphs with Neo4j and Cypher


Something important in a knowledge map is that is has to be as simple as possible.
For example, let's say the node A depends on node B and node B depends on Node C:

A->B->C

This tree is identical, in the context of a knowledge map, to this more complex one:

A->B-C
|->C

In this case, the brach from A to C is reduntant as this relation is contained in the branch A->B->C.

A way to simplify this second tree is using Neo4j and Cypher.

We can create the tree this way:

create (nodeA{name:'nodeA'}), (nodeB{name:'nodeB'}), (nodeC{name:'nodeC'}), (nodeA)-[:DEPENDS]->(nodeB), (nodeB)-[:DEPENDS]->(nodeC), (nodeA)-[:DEPENDS]->(nodeC)

To simplify it just execute this Cypher query:

match a-[r:DEPENDS]->c
where a-[:DEPENDS*2..]->c
delete r

Here we are deleting all the DEPENDS relations that connect two nodes where there is another longer path connecting them.

In this case, the relation to delete is A-C as there is another longer path: A->B->C
Try it yourself: console.neo4j.org