Páginas

2009/11/20

Sacar un XSD desde un XML

Pasar sacar un esquema inferido desde un archivo XML en .NET (C#), podemos hacer lo siguiente:

(Aplicación de consola)

XmlReader _reader = XmlReader.Create(_pathFicheroXML);
XmlSchemaSet _schemaSet = new XmlSchemaSet();
XmlSchemaInference _schema = new XmlSchemaInference();
_schemaSet = _schema.InferSchema(_reader);
foreach (XmlSchema _schemaObj in _schemaSet.Schemas())
{
  _schemaObj.Write(Console.Out);
}

2009/11/18

El problema de mostrar los certificados del almacén CertificateAuthority

Si alguna vez habéis intentado sacar los certificados por almacén, es posible que hayáis tenido problemas al mostrar el almacén CertificateAuthority en concreto.

Para sacar el listado de certificados yo hacía lo siguiente:

private Array listaDeAlmacenes()
{
    return Enum.GetNames(typeof(StoreName));
}

private IList certificadosPorAlmacen(string almacen)
{

        IList listaCertf = new List();

        try
        {
            X509Store store = new X509Store(almacen, StoreLocation.CurrentUser);

            store.Open(OpenFlags.ReadOnly);

            X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;

            foreach (X509Certificate2 certificado in collection)
            {

        ….. (etc)
   

listadeAlmacenes() devuelve en este caso, un array de strings de 8 elementos:


[0]: "AddressBook"
[1]: "AuthRoot"
[2]: "CertificateAuthority"
[3]: "Disallowed"
[4]: "My"
[5]: "Root"
[6]: "TrustedPeople"
[7]: "TrustedPublisher"


Cada una de estas cadenas se pasan al método certificadosPorAlmacén() y todo funciona bien exceptuando el caso de CertificateAuthority que no devolvía nada.

La solución la encontré rascando por internet y concretamente en: http://www.koders.com/csharp/fid7DCF8CE37E137FCC9549AD6DC0FCB4BEA690F50F.aspx

Este enlace nos lleva a la clase Mono.Security.X509 donde podemos ver el desarrollo que se ha hecho de la clase similar de Microsoft.

Me llamó la atención este método:

private static string StoreNameToString (StoreName sn)
        {
            switch (sn) {
                case StoreName.CertificateAuthority:
                    return "CA";
                default:
                    return sn.ToString ();
            }
        }

Pues bien, aquí está la solución: solamente hace falta cambiar el nombre de "CertificateAuthority" a "CA" para que funcione.

 
Sabiendo esto, cambié mi método de la siguiente forma:


private List listaDeAlmacenes()
    {
       
        List lista=new List();

        foreach (string sn in Enum.GetNames(typeof(StoreName)))
        {
            lista.Add(sn);
        }

        //Aquí se realiza el cambio
        lista[Array.IndexOf(lista.ToArray(), "CertificateAuthority")] = "CA";


        /* También valdría:
         *
        lista = Enumerable.Union(
            lista.Where(p => p != "CertificateAuthority"),
            Enumerable.Repeat("CA", 1)).
            ToList();
        */

        /* Y también:
        if (lista.Contains("CertificateAuthority"))
        {
            lista.Remove("CertificateAuthority");
            lista.Add("CA");
        }
        */

        return lista;
    }

2009/09/29

Número a literal en javascript

Hace tiempo estuve trabajando en una empresa que ofrecía sus servicios de programación a notarías.
Es bien sabido que en los documentos notariales toda cifra o número viene acompañado de su literal.
El programa original lo hice en lenguaje Fox  y lo he reconvertido y reescrito en javascript para que pueda ser aprovechado en el mundo web.

Bien, para utilizarlo debemos incluir la librería aLiteral.js que está alojada en https://github.com/17cosas/aLiteral.js , y crear un objeto aLiteral pasándole como argumento el número que queramos convertir, de esta forma:


var numeroLiteral = new aLiteral("23");
alert(numeroLiteral); // veintitrés


Un ejemplo más completo como pasar a literales el rango 0-100, podemos hacer lo siguiente:

                    function empieza()
                    {
                        for (var i=0; i<101; i++){
                            document.write(new aLiteral(i));
                        }
                    }
                    window.onload = empieza;


Cuyo resultado será:

cero
uno
dos
tres
cuatro
cinco
seis
siete
ocho
nueve
diez
once
doce
trece
catorce
quince
dieciséis
diecisiete
dieciocho
diecinueve
veinte
veintiuno
veintidós
veintitrés
veinticuatro
veinticinco
veintiséis
veintisiete
veintiocho
veintinueve
treinta
treinta y uno
... etc (hasta 'cien')



Enlaces:

http://es.wikipedia.org/wiki/Nombres_de_los_n%C3%BAmeros_en_espa%C3%B1ol

2009/09/16

Primer libro sobre Flex 4 (Gumbo)

Peter Armstrong se ha puesto manos a la obra para escribir el primer libro sobre Flex 4 (a.k.a Gumbo):  Hello! Flex 4.

De momento solamente podemos ver el primer capítulo que se ofrece gratuitamente: http://www.manning.com/armstrong3/armstronghello_meapch1.pdf


Su editorial es Manning y constará de 225 páginas.

Referencias:
http://www.manning.com/armstrong3/
http://www.manning.com/armstrong/
http://www.peterarmstrong.com/

Hola Mundo en Flex 4 (Gumbo)


<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- holamundo.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/halo"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script>
<![CDATA[
private function muestraHola():void {
miTextArea.text="Hola Mundo!";
}
]]>
</fx:Script>

<s:Panel title="miPanel">
<s:layout>
<s:VerticalLayout/>
</s:layout>

<s:TextArea id="miTextArea"/>

<s:Button label="Pulsa aquí" click="muestraHola();"/>
</s:Panel>
</s:Application>


Resultado:




Tendremos que seguir los mismos pasos que los descritos en: http://17cosas.blogspot.com/2009/09/hola-mundo-en-flex.html

exceptuando que el compilador Flex en este caso es de la version 4, alojado en http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4


Cabe resaltar los nuevos namespaces referentes a Halo y Spark:

* xmlns:fx="http://ns.adobe.com/mxml/2009" (MXML)

    Este namespace incluye los elementos de alto nivel del lenguaje ActionScript como son Object, Number, Boolean, Array, etc. Para ver la lista completa de estos elementos, ver la referencia del lenguaje de Adobe en el apartado 'Top Level' (http://livedocs.adobe.com/flex/gumbo/langref/)
   
    Este namespace también incluye las etiquetas que trata el compilador como , y . Para más información consultar la referencia del lenguaje de Adobe en el apartado MXML Only Tags.
   
    Este namespace no incluye los componentes Halo o Spark.
   
    También podemos ver la lista completa de elementos que contiene este namespace declarados en el fichero incluído en el SDK en frameworks\mxml-2009-manifest.xml

* xmlns:mx="library://ns.adobe.com/flex/halo" (HALO)

    Este namespace incluye todos los componentes de los paquetes mx.*, componentes gráficos (Flex charting components), y componentes de visualización de datos.
   
    Para obtener una lista completa de estos componentes podemos obtenerla en el manifiesto ubicado en el mismo directorio del SDK, framework\halo-manifest.xml
   
* xmlns:s="library://ns.adobe.com/flex/spark" (SPARK)

    Este namespace incluye todos los componentes de los paquetes spark.* y las clases de texto incluídas en los paquetes flashx.*
   
    También incluye los componentes RPC, y las clases RPC necesarias para tratar con los componentes WebService, HTTPService y RemoteObject. Estas clases están incluídas en el namespace mx:, pero por conveniencia también se pueden usar con el namespace s:
   
    La lista completa de estos elementos podemos encontralos en el manifiesto frameworks\spark-manifest.xml
   

Para saber más acerca de este nuevo framework remito a la información ofrecida por Adobe (http://livedocs.adobe.com/flex/gumbo/), aunque hay que recordar que está en beta y su contenido puede ser modificado.



Referencias:
http://www.ria212.com/node/9
http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4
http://livedocs.adobe.com/flex/gumbo/

2009/09/13

Reloj con el tag html <canvas>

He estado probando esta nueva etiqueta html solamente implementada por el momento en los navegadores Firefox, Safari y Opera.

He creado un reloj analógico con 'milisegundero' opcional. Para usarlo incluir lo siguiente:

1) Añadir la librería javascript relojcanvas.js, situada en mi página personal GitHub https://github.com/17cosas/RelojCanvas

2) Añadir el tag html <canvas>, por ejemplo:

<canvas height="200" id="micanvas" width="200" > 

Tu navegador no soporta el tag html <canvas>
</canvas>


3) Crear un objeto con las diferentes opciones que permite la clase, por ejemplo:


var reloj=new RelojCanvas({
            id: 'micanvas',
            radio: 90,
            conSombra: true,
            conMilisegs: true
            });
       
        reloj.start();





El resultado es el siguiente:
 


Referencias:
http://canvaspaint.org/ (un buen ejemplo de lo que se puede conseguir con este tag)
http://www.xs4all.nl/~peterned/3d/ (y otro magnífico ejemplo de canvas en 3d)




2009/09/11

Etiqueta html <video> en Firefox 3.5

Firefox 3.5 trae dos nuevas etiquetas html para tratar fácilmente archivos multimedia: <audio> y <video>

Por el momento solamente se pueden utilizar archivos Wav y Ogg Vorbis para el audio, y Ogg Theora para el vídeo.

He aquí un ejemplo:


<video id="mivideo" src="http://upload.wikimedia.org/wikipedia/commons/e/ec/Breitenlee-Windpark-320x240.ogg" controls="true"/>




Referencias:

https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox

http://www.theora.org/
http://www.vorbis.com/
http://www.xiph.org/

2009/09/10

Hola Mundo en Flex

Este artículo es escueto pero da una idea del lenguaje MXML de Flex:

Necesitaremos lo siguiente:

1) Un editor de textos tipo Notepad, Notepad++ o vi
2) El SDK de Flex, que se ofrece gratuitamente en
http://www.adobe.com/products/flex/flexdownloads/
o
http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+3



Creamos el fichero holamundo.mxml con un editor de textos añadiendo este código:


<mx:application mx="http://www.adobe.com/2006/mxml">
<mx:panel title="Applicación Hola Mundo!" paddingtop="10"
paddingbottom="20" paddingleft="10" paddingright="10">

<mx:label text="Hola Mundo!" fontweight="bold" fontsize="24">
</mx:label>
</mx:panel>
</mx:application>


Después lo compilaremos desde consola con la herramienta mxmlc.exe alojado en el directorio \bin del SDK de Flex, por ejemplo, en mi caso:

mxmlc g:\mi.flex\pruebas\holaMundo.mxml





Si no ha habido ningún fallo en la compilación nos aparecerá este mensaje:

Loading configuration file c:\flex_sdk_3.4\frameworks\flex-config.xml
G:\mi.flex\pruebas\holaMundo.swf (182272 bytes)

Con esto se habrá creado el archivo holaMundo.swf, y el resultado es el siguiente (visto con Firefox):

Sobre los valores nulos (null values) en las bases de datos

¿Qué es un valor null? NULL NO es un valor cero, NO es un FALSE y NO es un cadena vacía. ¿Qué es entonces?

NULL hace referencia a un valor desconocido, y es desconocido porque todavía no lo hemos podido encuadrar y clasificar en nuestra lógica de negocio o en nuestro domain language y que no hemos podido trasladar a nuestra base de datos.

NULL es un valor al que no le hemos encontrado cabida en la forma de interpretar las relaciones y fuentes de información de la empresa. Es un valor no definido y no contemplado por el momento, pero que, con una reflexión adecuada, puede ser sustituido y tratado adecuadamente.

Un gran número de ejemplos he visto en bases de datos empresariales: establecer a NULL un segundo apellido de un cliente extranjero, cantidades en una tabla de stock de almacén, categorías de estados no definidos correctamente, etc.

Se suele hacer la mala práctica de tomar a NULL como comodín para todo aquello que sale de lo establecido y lo no contemplado, llenando la base de datos de estos valores. Y llenar una base de datos con valores nulos supone incrementar la incertidumbre, cosa que va contra sus principios, puesto que se crearon para ofrecer información estructurada y precisa.

Y el problema es que los valores NULL son muy difíciles de tratar, explotar y operar. Por ejemplo al realizar estadísticas, podemos enumerar cuarenta valores y solamente sumar en un balance veintidós de ellos, porque estos valores nulos no son tratados.

Otros problemas pueden venir por su operabilidad: ¿Qué resultados se obtienen de operar booleanos con nulos? ¿Cómo se comporta una función agregada de SQL Server al encontrarse con nulos? ¿El resultado reflejará realmente lo esperado?

Tampoco podemos olvidar que si estamos acostumbramos a trabajar con nulos debemos tratar esta característica en un 70% de nuestras consultas SQL como por ejemplo, añadiendo la función ISNULL() o convirtiendo los valores nulos a cero, cosa que puede complicar el tratamiento de datos.

Así pues y en conclusión decir que siempre y cuando no podamos evitarlo, no utilizaremos valores nulos en nuestra base de datos.

Ahora bien, ¿qué podemos hacer cuando tenemos una columna que refleja un segundo apellido y que incluye valores nulos? La ausencia de un segundo apellido puede indicar que el cliente es extranjero, así pues podemos optar por estas dos opciones por ejemplo, cambiar los campos nulos a cadenas vacías o, por la que me decanto, rediseñar la base de datos e incluir una tabla nueva dedicada a clientes extranjeros sin segundo apellido.

¿Qué hacemos con las cantidades del almacén donde hay valores nulos? Si una cantidad aparece nula en la tabla de almacén seguramente sea porque esa cantidad de producto no existe o no se ha recibido. No podemos establecer a cero porque realmente no se ha recibido, y sería una fuente de controversias pues podría dar la posibilidad de pensar que hubo movimientos de stockaje en el pasado. Así pues, la solución vendría por crear una tabla con productos aún no recibidos o no dados de alta en el almacén y rediseñar las tablas implicadas. Así eliminamos los valores nulos y ofrecemos una información más veraz.

Enlaces:

http://www.bennadel.com/blog/85-Why-NULL-Values-Should-Not-Be-Used-in-a-Database-Unless-Required.htm
http://databases.about.com/cs/sql/a/aa042803a.htm
http://www.databasedesign-resource.com/null-values-in-a-database.html
http://www.databasedev.co.uk/null_values_defined.html

Error al ejecutar el compilador de Flex por ausencia de la librería MSVCR71.dll

Al ejecutar en un Windows Vista Home, el compilador de Flex 3.4 (mxmlc.exe) desde consola, se me ha mostrado el siguiente error:


Error loading: C:\Programa Files\Java\jre6\bin\client\jvm.dll


Y acto seguido, en una ventana emergente:

Mxmlc.exe – No se puede encontrar el componente
Error al iniciar la aplicación porque no se encontró MSVCR71.dll. La reinstalación de la aplicación puede solucionar el problema.











Bien, la solución pasa por lo siguiente:

1) Bajar la librería MSVCR71.dll de la siguiente página:
http://www.dll-files.com/dllindex/dll-files.shtml?msvcr71

2) Alojar esta librería en c:\windows\system32, o en el mismo directorio donde se encuentra el compilador, en mi caso, en c:\flex_sdk_3.4\bin

2009/07/21

Objetos y clases en javascript: prototype, constructor y closures


Creando Objetos


Un objeto en javascript es una coleccion no ordenada de propiedades, que puede incluir primitivas, otros objetos o funciones. Es decir, es un array de valores no ordenados.

Las formas de crear objetos en javascript son varias:

 Las clases en javascript no utilizan la palabra Class como en otros lenguajes. Para crear clases en javascript utilizaremos la palabra function.

Esta tercera forma (la c) se utiliza desde la versión 1.1 de Javascript y se le denomina función constructora o constructor de la clase, (no confundir con la propiedad constructor de una función que veremos más adelante). Con esta forma creamos una función que nos servirá en el futuro para que un objeto se instancie a partir de esta ,es decir, necesitaremos la palabra clave new para crear el objeto basado en esta función.

 [Instanciar quiere decir crear un nuevo objeto con la palabra new a partir de una clase]


Por ejemplo, si queremos hacer un objeto de cocheDeModa de tipo Coche haremos lo siguiente:




El objeto cocheDeModa ahora contiene la función 'Coche' dentro su propiedad llamada constructor. Veámoslo:



Constructores

Todo objeto tiene una propiedad intrínseca llamada constructor que hace referencia a la función constructora que inicializa el objeto. Los constructores son funciones, que a su vez, son objetos. Es decir, todo 'constructor' de un objeto es una función, que se hereda de Function, y que es también una instancia de Object, por lo que diremos que en Javascript, todo es un objeto (todo se extiende de Object).

El resultado es:

Veamos ahora el tipo de objeto que se crea en cada caso (para saber el tipo de un objeto podemos utilizar tanto typeof, constructor o instanceof):


Hay un problema con el operador typeof en el propio lenguaje Javascript al evaluar un objeto tipo Array y al evaluar los valores null, como nos cuenta Douglas Crockford (http://javascript.crockford.com/remedial.html)
Para ello utilizaremos su función para tratar correctamente con typeof:



Chequeamos tipos a través de constructor:

cocheDeModa es un objeto como nos dice typeof/typeOf(), pero también es una instanciación del objeto tipo Coche. Para saber de quién instancia podemos utilizar el operador instanceof:

Creando clases

Antes de nada decir que Javascript no crea clases de igual forma a Java, C++ o C#. Javascript no es un lenguaje orientado a objetos puro, aunque sí podemos decir que todo dentro del lenguaje es un objeto, y podemos emular ciertas partes de la programación orientada a objetos.

Vamos a crear dos 'clases' genéricas por medio de funciones constructoras que nos servirán como molde para hacer coches. Para establecer las propiedades y métodos utilizaremos el operador this.


Prototype y la herencia

Los objetos pueden crear nuevos objetos y también pueden 'heredar' unos de otros, bajo un nuevo concepto denominado herencia prototipal. Los programadores aconstumbrados a la herencia clásica de los objetos verán una forma novedosa de herencia basada en el prototipo. Es aquí donde entra en juego la propiedad prototype.

Cuando creamos una función constructora (una 'clase'), Javascript crea una propiedad llamada 'objeto prototipo' o 'prototype object'. Cuando creamos un objeto en javascript se heredan/extienden las propiedades de su prototipo.

Cuando utilizamos la siguiente expresión:

function F()

se crea automáticamente una nueva propiedad (que es, a su vez, un objeto)

F.prototype

y este, a su vez se enlaza con el genérico Object.prototype.

A partir de ahora, si añadimos nuevas funciones y propiedades a F.prototype, todos los objetos creados a partir de F(), heredaran las nuevas funcionalidades.


En Javascript, todo se hereda de Object.prototype, esta es la verdadera fuente de herencia. Si queremos cambiar cualquier variable u objeto del programa, solamente extenderemos desde aquí.
Como ejemplo Number.prototype hereda de Object.prototype. Si modificamos o añadimos algún método a Number, al invocar a este método, primero se busca en el prototipo de Number y si no se encuentra, subirá hasta Object.prototype para encontrarlo. Lo mismo ocurre con los demás objetos de javascript.
De aquí podemos deducir que:

alert(oJose.constructor === Persona.prototype.constructor); // true


El constructor de un objeto es equivalente al constructor del prototipo de la clase de la cual instancia. O dicho de otro modo, tanto la función constructora como el constructor de su prototipo, son del mismo tipo (menuda frase).


En Javascript, cada vez que instanciamos un objeto, se hace una copia literal de todo el objeto en la memoria, es decir, se copian todas las propiedades y métodos por cada objeto creado, con el gasto de memoria que ello implica.
Siguiendo el ejemplo anterior, tanto unCocheDeModa como otroCocheDeModa existen en memoria con las mismas propiedades y métodos.
Siendo las propiedades las que más varían su valor, se entiende que cada objeto tenga las suyas propias, pero ¿y los métodos? acelera() siempre devolverá 'Bruumm' y getColor siempre nos dará el color del coche. Así pues podemos extraer estos métodos comunes y ponerlos bajo la propiedad prototype, esto ahorrará memoria.
Se puede decir que así extendemos también los métodos de la superclase.

Los nuevos objetos que instancien de Coche serán mucho más ligeros en memoria y enlazarán directamente con Coche.prototype cuando se llame a los métodos acelera() y getColor().


Heredando/extendiendo

Veamos un ejemplo ahora que ya sabemos cómo funciona prototype, veamos un ejemplo de herencia clásica:

Resultando:

Viendo lo anterior, podemos hacer una función que nos facilite la extensión:

El problema aquí es que si superClase es muy grande y la instanciamos gastaremos mucha memoria. Así pues una solución es aplicar una función 'puente' en la que asignemos a su propiedad prototype el prototipo de la superclase:


Aplicándolo al ejemplo anterior:



Herencia prototypal

Lo visto anteriormente es la denominada herencia clásica en javascript que intenta simular la herencia de la programación orientada a objetos. Ya que Javascript usar los prototipos, vamos a hacer uso de ellos para crear extensiones.

La diferencia entre los dos tipos de herencia es que mientras la clásica necesita de funciones constructoras, la prototypal se fija solamente en el objeto. La creación de un objeto será el prototipo para todos los demás, y no es más que una copia de su propiedad prototype.


Cuándo utilizar el tipo de herencia más adecuado dependerá del programa. Los pros de la herencia clásica es que es más fácil de leer y permite utilizar funciones constructoras. Los contras, el consumo de memoria. En cambio la herencia prototypal es más ligera, pero se limita a la creación de objetos. La decisión dependerá del resultado final y del propio programador.




Para profundizar más, no dejar de leer el artículo escrito por Shelby H. Moore 'Correct OOP for Javascript'
(http://www.coolpage.com/developer/javascript/Correct%20OOP%20for%20Javascript.html)
o 'Javascript Prototypal Inheritance, My 5 Cents From Web Reflection'
(http://www.3site.eu/doc/)



Un paso más allá de la herencia

Uno de los fundamentos de la extensión es que se pueda llamar a los métodos del objeto que extiende (o comúnmente 'padre').

Desde Javascript 1.3 disponemos de dos funciones llamadas call y apply que permite ejecutar un método de otro objeto. Su sintaxis es:

call (objeto, argumentos);

objeto será aquel objeto en el cual recaerá la ejecución de la función

apply (objeto, [argumentos]) ,igual que call exceptuando que los argumentos se pasan como un Array.

Ejecutar esto

Area.call(obj, base, altura);


es lo mismo que:

obj.metodo = Area;
obj.metodo(base,altura);
delete obj.metodo;


Bien, pues para extender los métodos de la clase 'padre' debemos hacer lo siguiente:


Ámbito de las variables

Seguramente sepas que el objeto que engloba todas las variables globales es window, que es a su vez global también.

Las dos sentencias siguientes son equivalentes:
Es lógico que si una variable se declara fuera de una función se haga global, hasta aquí todo normal, pero miremos el siguiente caso:
Curiosamente, propiedad pasa a ser global aun estando dentro de una función. Esto pasa porque el operador this hace 'públicas' las variables y los métodos (muy importante recordar esto).

No ocurre lo mismo si declaramos una variable dentro de una función (ámbito local):
En el primer ejemplo, al llamar a la función Prueba() lo hemos hecho dentro de un ámbito global y por tanto su propiedad también lo era. Si a esta función constructora / 'clase' la instanciamos dentro de una variable 'p', el objeto global window no tendrá acceso a él, no de una forma directa, con lo que nos ahorramos un poco de memoria:

Ámbito de los métodos: públicos, privados y privilegiados

Siguiendo a Douglas Crockford (http://javascript.crockford.com/private.html), el ámbito de los métodos serán los siguientes:

* Métodos Públicos, los métodos públicos son completamente accesibles dentro del contexto del objeto.

- Desde el constructor. Con el operador this, hacemos públicos los métodos como ya hemos visto.

- Desde el objeto prototype. También visto anteriormente, prototype nos permite hacer públicos los métodos:

Utilizando la funcion prueba anterior...

* Métodos Privados. Métodos que solamente son accesibles desde el propio objeto, ya sea desde otros métodos privados dentro de él mismo, otras variables privadas que contenga o otros métodos privilegiados (como veremos más adelante). Los métodos privados son muy importantes ya que permiten una correcta gestión del código sin que se produzcan coincidencias con otros objetos.

* Métodos Privilegiados. Es una combinación de los dos anteriores. Ya que los métodos privados no son accesibles desde el exterior, si queremos obtener sus valores debemos hacer un puente entre lo público y lo privado. Como ya hemos visto en el ejemplo anterior, this.capitaliza es un método que se hace público devolviendo una operación privada (unionLetras), éste es un método privilegiado.


La mayor diferencia entre los tres es que únicamente nuevos métodos públicos pueden añadirse una vez creado el objeto. Los privados y privilegiados deben establecerse en la función constructora.


Closures, Cierres o Clausuras

Desde que Javascript en su creación se vió influenciado por otros lenguajes como Scheme o Self, este adoptó los denominados closures o clausuras (aunque a mi me gusta más el termino cierre).

Indagando por Internet en busca de una definición que explicara los cierres de una forma menos académica, he encontrado la mejor a mi parecer en la Wikipedia que dice así:

"En Informática, una clausura es una función que es evaluada en un entorno conteniendo una o más variables dependientes de otro entorno. Cuando es llamada, la función puede acceder a estas variables... En algunos lenguajes, una clausura puede aparecer cuando una función está definida dentro de otra función, y la función más interna refiere a las variables locales de la función externa. En tiempo de ejecución, cuando la función externa se ejecuta, una clausura se forma, consistiendo en el código de la función interna y referencias a todas las variables de la función externa que son requeridas por la clausura... Una clausura puede ser usada para asociar una función con un conjunto de variables 'privadas'..."

Esta sentencia puede explicarse visualmente así:
incremento(x) es una función que devuelve otra función. El cierre es function(y) y opera con la variable x declarada exteriormente.

Otro ejemplo:
La manera más usual de crear closures es devolviendo funciones anidadas. Una funcion hija puede tener acceso al entorno de la función padre siempre que este haya completado su ejecución.

¿Por qué son importantes las clausuras? Porque aparte de que ofrecen flexibilidad, permiten crear variables que solamente pueden ser accesibles internamente.


Funciones anónimas

Una función anónima es aquella que no tiene nombre. Por ejemplo:
Normalmente, siguen este patrón:

(function () { ... }) ();


Pero también puede valer:

var foo = function(x) {return (x*x);};

Otro ejemplo dado por Dustin Diaz (http://www.dustindiaz.com/scoping-anonymous-functions/)
Las funciones anónimas suelen ser utilizadas:
- para ejecutar código una sola vez y se ejecutan de inmediato.
- para tratar mejor su contenido, haciéndolo privativo: esconden código que solamente es accesible dentro del objeto. Los objetos dejan de ser globales.
- ahorrar memoria


Quitando las referencias a los objetos

var obj=new Object();
obj=null;


Asignando a null rompemos la referencia y destruimos el objeto para que más tarde el Garbage Collector de javascript lo limpie de la memoria.


JSON

Como hemos dicho antes, un objeto puede declararse así:
Pero también se puede declarar así en formato JSON:
Que es muy similar al resultado dado por la función toSource() del objeto String.

alert(oCocheDeModa.toSource());

Con esto creamos el objeto inmediatamente, ya está instanciado. Su constructor será Object. OJO!: estaremos creando un objeto no una 'clase' / función


Extendiendo los objetos propios de Javascript

Después de todo lo visto, vamos a hacer un ejemplo extendiendo algunas funcionalidades extra del objeto String de Javascript:

El objeto String no dispone de las funciones 'trim' que existen en otros lenguajes. Trim, RTrim (right trim) y LTrim (left trim) quitan los espacios del inicio y final de una cadena, del inicio solamente o del final, respectivamente.
Para añadir estas funciones de una forma pública y que todos los objetos tipo String puedan utilizarlas, debemos modificar la propiedad prototype.

(Actualizado 29-ago-2013)
Seguramente te preguntes viendo el código anterior, ¿no puedo reescribirlo en formato JSON de la forma?:
Siento decir que la respuesta es que no, porque la propiedad prototype de String es 'readonly' (de sólo lectura) y no se le puede asignar código directamente. (http://stackoverflow.com/questions/8613907/why-string-prototype-wont-work)

Últimos apuntes


* Sentencias equivalentes

- Declarar una variable en un ámbito global como

 var texto="texto";

equivale a

  window.texto="texto";

- Una función cuando se declara, se le asigna una variable por defecto.

function f(){
   return 'una función';
};


equivale a

var f=function(){
   return 'una función';
};



* == y ===

Tanto == como === comparan los valores a ambos extremos del operador, pero con una gran y sutil diferencia. Mientras == sólo compara valores, === además compara los tipos. Es sorprendente como Javascript puede hacer las siguientes cosas:

'1' == 1 //true
null == undefined //true


En cambio, de una forma mucho más lógica:

'1' === 1 //false, un String no es un Number
null === undefined //false
'1' === '1' //true

Se recomienda utilizar === en casi todos los casos de comparación por ser más riguroso.



Referencias

http://javascript.crockford.com/survey.html
http://javascript.crockford.com/remedial.html
http://javascript.crockford.com/private.html (ambito de los métodos)
http://webreflection.blogspot.com/2007/03/javascript-constructor-did-you-know.html (una función Constructor muy interesante)
http://www.coolpage.com/developer/javascript/Correct%20OOP%20for%20Javascript.html ('Correct OOP for Javascript)
http://www.3site.eu/doc/ ('Javascript Prototypal Inheritance, My 5 Cents From Web Reflection')
https://work.dustindiaz.com/
http://www.javascriptkata.com/

2009/07/14

Buenas prácticas en la programación

Autores como Dave Thomas, Martin Fowler, Kent Beck, Robert Cecil Martin o Rebecca Wirfs-Brock coinciden en unas prácticas que un desarrollador debería seguir o que un programa debería contener:



1) El principio DRY, 'Don't Repeat Yourself' o 'No te repitas'. Citado por primera vez por Dave Thomas en su libro The Pragmatic Programmer. Este principio se resume en que a menudo, nuestro código repite sentencias o trozos de código para un mismo fin. Cuando veamos que esto ocurre, saquemos estas sentencias e introduzcámoslas en una función, si esta función la utilizamos muchas veces, encapsulémosla en una clase. Si esta clase junto con otras dan una solución a un problema repetido, hagamos un patrón de diseño, y así sucesivamente. El fin es no 'reiventar la rueda', pilar en la programación orientada a objetos.



2) Usar Refactoring. La definición formal de refactoring es 'el proceso por el cual cambiamos y mejoramos el software internamente sin que halla una alteración exterior en el comportamiento del mismo'. Este término fue oficialmente explicado por primera vez en 1999 por Martin Fowler en su libro Refactoring: Improving the Design of Existing Code. Si no lo has leído, te lo recomiendo.
En definitiva, el proceso de refactorizar un programa hace que éste sea mucho más legible, más limpio y más reusable sin que cambie la ejecución del programa. Primero se escribe el código y luego se refactoriza.
Es un conjunto de técnicas sencillas como por ejemplo acortar un método demasiado largo, cambiar su nombre para que realmente refleje lo que hace, colocar los métodos en las clases adecuadas, quitar parámetros cuando no hagan falta, etc. Seguramente te preguntarás para qué sirve cambiar de nombre una función o una variable si leyendo el código puedes intuirlo. Bien, los programadores además de programar, leemos mucho código. En un equipo de trabajo, la revisión de un programa escrito hace un año por un programador que puede estar ahora de vacaciones se puede complicar si tenemos variables llamadas como x, a[5], temp o FX45, funciones extralargas y clases cuyo nombre no reflejan su intención. Mucho más fácil es leer: altura, tiempo o articuloEnAlmacen. Si eres altruista mira por los compañeros y deja un código legible, si no lo eres, piensa que más tarde o temprano tendrás que revisar tu programa y te costará mucho más tiempo saber cómo funciona.

3) Testear. Hacer tests o pruebas sobre tu programa no se limita a que responda bien a un evento. Cuando hacemos click y se abre una ventana o se muestra un subtotal de una lista de precios estamos limitando el testeo. Testear en software lleva parejo técnicas como Unit Testing, Test-Driven Development, Mock Objects, Automatic Testing, etc. Todas ellas englobadas por primera vez en la metodología XP desarrollada por Kent Beck.
El testeo asegura la calidad del software y una disminución en la propensión a errores. Se prefiere hacer buenos tests a estar toda una mañana buscando un bug con un debugger.
Pero, ¿qué es hacer un testeo? Bien, testear, en su manera más formal, es hacer pruebas sobre un método o clase (no sobre la ejecución del programa) y que ésta responda tal como lo habíamos planeado.
Por ejemplo, cuando hagamos una función que calcule la raiz cuadrada de un valor, debemos comprobar que realmente devuelve un valor esperado, y, lo más importante, debemos pasarle como argumento valores posibles, imposibles y no contemplados. Me explico: el valor posible para una raiz cuadrada es un entero o un decimal positivo, un valor imposible un entero o decimal negativo, y un valor no contemplado podría ser un caracter alfanumérico, una cadena, una pulsación de una tecla o un valor nulo.
Aparte de las pruebas unitarias, también completaremos el testeo con una buena supervisión de la ejecución del programa, tanto a nivel de programador como a nivel de usuario.


¿Porqué estas prácticas? La razón es que el desarrollo del software es una disciplina que exige una contínua revisión. Un programa siempre tiende a la entropía, al desorden, si no se mantiene, se limpia y se cuida. Muchas veces hemos empezado a idear un programa, funciona idílicamente en nuestra cabeza, todas sus partes combinan perfectamente, esto devuelve tal cosa, aquello se une con esta otra... Empezamos a programar y a medida que el tiempo pasa, nuestro pograma se vuelve inestable: aquello que funcionaba perfectamente en nuestra temprana planificación se va desmoronando. 'Uy! no había contemplado esto!' 'Uy! ¿porqué no me muestra el valor?'
Todo esto a nivel individual y con un programa propio. Llevado a términos empresariales, con un gran equipo, y donde el dinero y los costes juegan un papel muy importante, las consecuencias son desastrosas. La solución es aplicar estas prácticas que se han englobado en las denominadas metodologías ágiles. Todas estas metodologías tienen como base lo descrito con sus diferencias propias. Aunque esto ya es harina de otro costal y se comentará más adelante.

MsiInv o cómo obtener información del software instalado en tu ordenador (en Windows)

Pues como dice el título, si quieres saber realmente qué software tienes instalado en tu computadora con el sistema operativo Windows, recom...