Zootropo

Diario del mundo geek.

sábado, julio 31, 2004

Sobre el bloqueador de popups de Firefox

La gente de Free Pop Up Blocker (descubierta en Adot's notblog*)tiene una comparativa de los mejores bloqueadores de pop ups gratuitos, ya sean integrados en los navegadores o como herramienta de terceros.

Y como era de esperar, al menos por mi, la mejor puntación entre todos los bloqueadores de popups del mercado, se la lleva Firefox, que tuvo un 100% en todos los tests.


Clasificación de bloqueadores

Añademe a...

viernes, julio 30, 2004

Destrozando clásicos del cine lección I: El Retorno del Jedi

Supongo (o mas bien espero, porque viniendo de George Lucas se puede esperar cualquier cosa) que esto debe ser un fake. Pero en teoría se anuncia como imagenes filtradas de los nuevos DVDs revisados de la Guerra de las Galaxias.

El video en concreto pertenece al final de 'el Retorno del Jedi', en las escenas en que aparece el fantasma de Anakin al lado del de Yoda y Obi-wan. Pues bien, si a George no le pareció suficiente ese insulto a la inteligencia que era 'La Amenaza Fantasma', con el maldito Jar Jar Binks, y después las guerras Clon, ahora se dedica a destrozar también las tres primeras películas de la saga, cambiando en las imagenes mencionadas al actor original, Sebastian Shaw, por el niñato que eligió para interpretar a Anakyn, Hayden Christensen.

Y no es que me importe demasiado, porque no soy fan de la Guerra de las Galaxias, simplemente me gustó la trilogía original, pero un chaval rubito con cara de niña pega mas como modelo de un anuncio de Pantem que como uno de los mejores villanos de la historia del cine.

La cosa va de escritorios

Si Chavalina y David enseñan sus escritorios, yo como buen ser envidioso que soy, no podía ser menos, aunque para dar un poco mas de interes al asunto voy a comentar que programas he usado.


Mi escritorio

El estilo visual es Method, de Sonus. Para aplicarlo en lugar de tener que usar un programa que consume recursos y además no es gratuito, como StyleXP uso MultiPatcher para parchear la dll que se encarga de los estilos visuales en XP, uxtheme.dll.

Los iconos de tamaño mayor del normal para la barra de inicio se consiguen con True Launch Bar, un programa de pago, aunque tiene una versión de prueba que muestra un texto advirtiendote de que no estas registrado en la barra de inicio. Los iconos, tanto de la barra de inicio como en el escritorio son una mezcla de Gant y Umicons, y aunque no se vea, todos los iconos, los diálogos como el de copiar archivos e incluso la pantalla de cierre de Windows tienen aspecto Gant gracias a GUI Replacer.

Una lista de todos los releases de Gant, Umicons, miniGANT,... podeis encontrarla en la sección en DevianART de su creador, Mattahan, así como en su página web, junto a otras cosas como wallpapers.

Por último, el calendario es Rainlendar, con el skin Shadow y el programa que mide la temperatura Samurize (esto en concreto ya expliqué como hacerlo en El tiempo en tu escritorio con Samurize

El escritorio Linux ya lo enseñaré cuando termine de luchar con SuperKaramba.

Las peores canciones de la historia

Cek y Topopardo publican listas de las canciones que mas les gustan en sus respectivos blogs (topopardo solo lleva dos, pero porque incluye los mp3s :P). Yo la publicaré de las que odio. Por que es mas facil, porque no te sientes mal por dejar algún clásico sin mencionar si la haces de las mejores, y sobre todo porque me gusta llevar la contraria.

Así que aquí está, the Zootropo's top ten de las peores canciones de la historia.

  1. Los del Río - Macarena, ese virus auditivo que llegó a contagiar a medio planeta.
  2. Las Ketchup - Aserejé, demostrando que para triunfar en verano solo se necesita una melodía machacona, una letra con el menor sentido posible y un baile para la canción.
  3. Georgie Dann - La Barbacoa, otro representante de las canciones del verano, que arrasan en el top ten. Este es de la escuela 'repite una frase un minimo de 200 veces en la canción'.
  4. Melody - El Baile del Gorila, otra que sabe que si la canción tiene baile el éxito está asegurado. Tiene menos crimen (o mas depende de como se mire) que el aserejé porque esta niña al menos se molesto en crear una letra, por muy estúpida que sea.
  5. Enrique Iglesias - Héroe, esa grabación que salió con el chico desafinando suena casi mejor que el original.
  6. Mª Jesús (con su inseparable acordeón) - El baile de los pajaritos, los animales hacen furor en nuestra lista.
  7. Paco Pil - Viva la fiesta, no se que habrá sido de este joven pastillero, himno de masas cuando aparecieron los primeros pseudo bakalas en el pais.
  8. King Africa - La Bomba, acabé tan harto de esta canción que todavía lloro por las noches al recordarla.
  9. 'Britney Spears - Ups, I did Again', lo malo es que lo hizo una vez, y otra, y otra, y desde que llegó no ha parado (de hacer canciones pésimas, se entiende).
  10. Demmis Rousso - Triki triki, otro que no se le entendía la letra, pero al menos era griego o algo así (creo).

Faltan bastantes canciones, pero como ya he dicho, es una de las ventajas de hacer listas de las peores, que no te dan remordimientos de dejar alguna sin poner.

Code Colorizer

CodeColorizer convierte el código fuente de lenguajes como ASP, C/C++, Clipper, Delphi/Pascal, HTML, Java, JavaScript y Visual Basic a documentos HTML con coloreado de sintaxis. Estuve buscando ayer algún programa o herramienta web que sirviera para eso, mas que nada porque ya había visto alguno y sabía que existía y no tenía que crear el mío propio :P y estoy contento con los resultados :)

Un ejemplo usando código Javascript del tutorial que estoy escribiendo:

function departamento(){
this.personal = new Array();
this.anyadir = anyadir;
this.calcularNomina = calcularNominaDept;
}

function empleado(nomina){
this.nomina = nomina;
this.calcularNomina = calcularNominaEmpl;
}

function anyadir(objeto){
this.personal.push(objeto);
}

function calcularNominaDept(){
var nomina = 0;
for(var i = 0; i < this.personal.length; i++){
nomina += this.personal[i].calcularNomina();
}
return nomina;
}

function calcularNominaEmpl(){
return this.nomina;
}

empresa = new departamento();
empresa.anyadir(new empleado(200));
empresa.anyadir(new empleado(100));
contabilidad = new departamento();
contabilidad.anyadir(new empleado(120));
empresa.anyadir(contabilidad);
document.write(empresa.calcularNomina());
function departamento(){
this.personal = new Array();
this.anyadir = anyadir;
this.calcularNomina = calcularNominaDept;
}

function empleado(nomina){
this.nomina = nomina;
this.calcularNomina = calcularNominaEmpl;
}

function anyadir(objeto){
this.personal.push(objeto);
}

function calcularNominaDept(){
var nomina = 0;
for(var i = 0; i < this.personal.length; i++){
nomina += this.personal[i].calcularNomina();
}
return nomina;
}

function calcularNominaEmpl(){
return this.nomina;
}
empresa = new departamento();
empresa.anyadir(new empleado(200));
empresa.anyadir(new empleado(100));
contabilidad = new departamento();
contabilidad.anyadir(new empleado(120));
empresa.anyadir(contabilidad);
document.write(empresa.calcularNomina());

Está claro que el código es mas legible (y mas bonito :P) después de pasarlo por el colorizer.

Nedstat

Ayer añadí un nuevo contador aparte del de Site Meter que tenía antes, el de Nedstat que es mas conocido y utiliza mas gente, mas que nada para comparar el número de visitas que me daban Site Meter y este. Y la verdad es que menudo cambio... no se como medirán cada uno, puede que Nedstat tenga un límite de tiempo entre páginas vistas menor que Site Meter para que sea considerado otra visita, pero el número de visitas es bastante mayor según Nedstat que según Site Meter. En concreto 242 según el primero, y 162 según el segundo, ¡lo cual supone una diferencia de 80 visitas!, que es bastante para un sitio que está sobre las 200.

Otra cosa interesante, y que aunque sea una tontería quieras que no hace algo de ilusión, es que me coloqué en el puesto 37 de los blogs mas visitados (de entre los que tienen contador Nedstat) según el Top 1000 de Nedstat :)

jueves, julio 29, 2004

Etiquetando los correos no leidos en Gmail

Parece mentira que cosas tan tontas sean tan útiles :) Leo en TimeLine un truco sacado de gmailwiki que consiste simplemente en crear una etiqueta (label) Unread en Gmail. Sin necesidad de crear ningún filtro ni similares Gmail marcará todo el correo no leido con esta etiqueta.

Javascript: Expresiones Regulares

Las expresiones regulares son una forma de describir cadenas de caracteres que sirven para comparaciones y reemplazos complejos. Por ejemplo si escribimos en la línea de comandos de windows dir *.exe, eso es una expresión regular que define todas las cadenas de caracteres que empiecen con cualquier cosa seguida de .exe, es decir, todos los archivos .exe. La acción de comparar la cadena de texto con el patrón que le hemos dado (la expresión regular) se denomina reconocimiento de patrones (pattern matching).

En Javascript las expresiones regulares se basan en las de Perl, de forma que son muy muy parecidas y se representan por el objeto RegExp (de REGular EXPresion). Para crear una expresión regular podemos usar el constructor del objeto RegExp, pero es mas conveniente utilizar una sintaxis especialmente pensado para ello. Veamos un ejemplo, el mas simple posible.

var patron = /pato/;

Este es el patrón mas sencillo. En una comparación con una cadena devolvería true en el caso de la cadena con la que se compara sea "pato". Todos los patrones se escriben entre barras invertidas, así como las cadenas de texto se escriben entrecomilladas. La otra forma de crear el objeto RegExp es como deciamos utilizando su constructor.

var patron = new RegExp("pato");

Pero en este caso lo que le pasamos al constructor es una cadena, por lo tanto en lugar de usar / lo entrecomillamos. Para complicar un poco mas las cosas supongamos que queremos comprobar si la cadena que nos pasan es pato, pata o pate. Entonces usariamos los corchetes, que indican opción, es decir, al comparar con /[aeo]/ devolvería cierto en caso de que la cadena fuera la letra a, la e o la letra o.

var patron = /pat[aeo]/;

¿Y si quisieramos comprobar si la cadena es pat0, pat1, pat2, ..., pat9? En lugar de tener que encerra los 10 dígitos dentro de los corchetes podemos utilizar el guión, que sirve para indicar rangos. Por ejemplo 0-9 serían todos los números de 0 a 9 inclusive.

var patron = /pat[0-9]/;

Si quisieramos por ejemplo que el último caracter fuera o un dígito (0-9) o una letra minúscula (a-z) simplemente se escribirían dentro de los corchetes un criterio detras de otro.

//pat seguido de un número o letra minúscula
var patron = /pat[0-9a-z]/;
//ahora también puede estar seguido de una A mayúscula
var patron2 = /pat[0-9a-zA]/;

¿Y que ocurriría si en lugar de tener solo un número o una letra minúscula quisieramos que pudieran haber varias, pero siempre minúsculas o números? Entonces recurrimos a +, *, ? y {}. + indica que lo que tiene a su izquierda puede estar 1 o mas veces, * indica que puede estar 0 o mas veces (en el caso de + el número o la minúscula tendría que aparecer al menos una vez, con * pat también se aceptaría), ? indica opcionalidad, es decir, lo que tenemos a la izquierda puede o no aparecer (puede aparecer 0 o 1 veces) y por último {} sirve para indicar exactamente el número de veces o que puede aparecer o un rango. Por ejemplo {3} indicaría que tiene que aparecer exactamente 3 veces, {3,8} indicaría que tiene que aparecer de 3 a 8 veces y {3,} tres veces o mas (las que sean). Hay que tener cuidado porque {} exige que se repite lo último, cuando no se esté seguro de lo que va a hacer usamos (). Para ilustrar esto vamos a ver un primer ejemplo real con expresiones regulares:

<script>
var patron = /pat[ao]{2}/;
document.write("patopata".search(patron));
document.write("patoa".search(patron));
patron = /(pat[ao]){2}/;
document.write("patopata".search(patron));
document.write("patoa".search(patron));
</script>

La función search del tipo de objeto de String (asociado a las cadenas de caracteres) comprueba si la cadena representada por el patrón que le pasamos como argumento se encuentra dentro de la cadena sobre la que se llama a search. En el caso de que así sea devuelve la posición (por ejemplo para la cadena pato con el patron /p/ devolvería 0, 1 si el patrón es a, 2 si es t,...) y -1 si no se encuentra. Otra función útil que merece la pena comentar es cadena.replace(patron, sustituto), que sustituye en la cadena sobre la que se llamó las ocurrencias del patrón por la cadena especificada

Si ejecutamos el programa anterior la salida por pantalla será -100-1, es decir, la primera y última llamada a search devuelven no encontrado y la segunda y las otras dos encuentran la cadena en la posición 0. Si nos fijamos vemos que esto es obvio. El patrón que definimos primero, /pat[ao]{2}/ incluye las cadenas "pataa", "patao", "patoo" y "patoa", ya que lo que indica {2} que debe repetirse dos veces es [ao], no pat[ao]. Sin embargo cuando redefinimos el valor del patron utilizamos los paréntesis de forma que {2} se aplique sobre pat[ao].

Otro elemento interesante en las expresiones regulares es la especificación de las posiciones en que se tiene que encontrar la cadena, esa es la utilidad de ^ y $, que indican que el elemento sobre el que actúa debe ir al principio de la cadena o al final de esta.

//buscamos "oo" y que se encuentre al principio de la cadena en la que esté
var patron = /^aa/;
//buscamos uu al final de la cadena
patron = /uu$/;

Otros elementos a tener en cuenta son:

  • \d un dígito. Equivale a [0-9]
  • \D cualquier caracter que no sea un dígito.
  • \w Cualquier caracter alfanumérico. Equivalente a [a-zA-Z0-9_].
  • \W cualquier caracter no alfanumérico
  • \s espacio
  • \t tabulador

Eliminar items del menú contextual de Firefox

Interesante este truco que he visto en el foro de Mozillazine. Como la apariencia de Firefox se define con archivos css, basta editarlos para modificar la apariencia de Firefox. En este caso para eliminar entradas del menú contextual. Tenemos que editar userChrome.css y establecer display a none para los items que no queremos que se muestren. Por ejemplo:

#context-setWallpaper, #context-blockimage{

display: none;
}

Una lista de las entradas posibles:

  • #context-back: "Back" (atras)
  • #context-blockimage: "Block images…" (bloquear imágenes)
  • #context-bookmarklink: "Bookmark this Link…" (añadir enlace a marcadores)
  • #context-bookmarkpage: "Bookmark this Page…" (añadir página a marcadore)
  • #context-copy: "Copy" (copiar)
  • #context-copyemail: "Copy Email Address" (copiar dirección de correo)
  • #context-copyimg: "Copy Image Location" (copiar dirección de la imagen)
  • #context-copylink: "Copy Link Location" (copiar dirección del enlace)
  • #context-cut: "Cut" (cortar)
  • #context-delete: "Delete" (borrar)
  • #context-forward: "Forward" (adelante)
  • #context-metadata: "Properties" (propiedades)
  • #context-openlink: "Open Link in New Window" (abrir enlace en nueva ventana)
  • #context-openlinkintab: "Open Link in New Tab" (abrir enlace en nueva pestaña)
  • #context-paste: "Paste" (pegar)
  • #context-reload:
    "Reload" (recargar)
  • #context-saveimage: "Save Image As…" (guardar imagen como)
  • #context-savelink: "Save Link As…" (guardar enlace como)
  • #context-savepage: "Save Page As…" (guardar página como)
  • #context-searchselect: "Web Search for…" (buscar en la web)
  • #context-selectall: "Select All" (seleccionar todo)
  • #context-stop: "Stop" (parar)
  • #context-setWallpaper: "Set As Wallpaper" (establecer como imagen de fondo)
  • #context-undo: "Undo" (deshacer)
  • #context-viewbgimage: "View Background Image" (ver imagen de fondo)
  • #context-viewimage: "View Image" (ver imagen)
  • #context-viewinfo: "View Page Info" (ver información de la página)
  • #context-viewpartialsource-mathml
  • #context-viewpartialsource-selection:
    "View Selection Source" (ver código fuente de la selección)
  • #context-viewsource: "View Source" (ver código fuente)

Porno Infantil

He estado echando un vistazo a las estadísticas de las búsquedas y los referers de los blogs mas visitados según nedstat y lo que he visto me ha parecido curioso. Es impresionante que para un blog como el gran escolar el segundo resultado de búsqueda a estas horas sea 'porno' con 16 búsquedas. El primero es infantil y lo que estareis pensando muchos se confirma al ver los referers. Seis búsquedas en google con el texto 'porno infantil'. Cuando ves que otras búsquedas son: 'las torturas de soldados americanos en Iraq' empiezas a preguntarte si esta gente esta bien del coco, aunque queda la duda de si será gente buscando información sobre el tema y no fotos, que esperemos que sea eso :/

La entrada de escolar a la que lleva el enlace en google es un artículo sobre la conveniencia o no de que sea delito el distribuir porno infantil, que Nacho compara con prohibir Lolita, de Navokob y en los comentarios se compara con prohibir CSI porque se ven asesinatos. Quitando el hecho de que no este de acuerdo, porque en CSI no se asesina de verdad y en el porno infantil si se esta cometiendo un delito es un artículo que te hace pensar.

Y siguiendo con lo que vamos, en los comentarios al artículo se encuentran joyas como:

me gusta que los niños me chupen el guebo
mientras mas pequeños mejor

soy una persona NORMALLLLLLLLL

me los voy a cojer a todos

Suena a coña. Si el tío lo dice en serio está bastante mal.

ME GUSTARIA FOLLAR A ESAS MUCHACHITAS, MANDENME FOTOS PARA MASTURBARME A MI CORREO YA QUE TAMBIEN ME FROTARE EL CHORIZO, SI ALGUNA CHICA DESEA VERME EN CAM INSCRIBASE A MI MSN PERO QUE TENGAN TAMBIEN FOTOS O CAM, ME DESPIDO CON UN PENETRAZO A TODAS EN EL CULO BYEEEEEEEEEEEEEEEE
DIOGO 100$$

Otro gilipollas mas aburrido que el primero.

yo pienso que esta bien lo que hacen porque a mi me facina ver como tienen relaciones sexuales los menores de edad

Este si puede que este diciendo lo que piensa pero me inclino por la teoría 'me aburro, voy a poner un comentario estúpido para buscar bronca'. Y luego tenemos los payasos varios que habrán llegado buscando porno infantil en google.

quiero que me manden fotos de niñas yo tengo desnudas intercambio
mandame fotos te intercambio
Yo creo que la sexo es lo mas hermoso que puede haber esto lo digo en forma personal.
Me gustaria conseguir videos de niñas infantiles menores de 15 años. No se si podrian darme informacion en donde conseguier.
blancos teodoro
E-mail blancosvenancio@latinmail.com
PERU
me gustaria ver videos pornos con niñas menores de quince mandenme aunque sean cortos les voy a agradecer son lo maximo sigan no hagan caso la vida es asi escribanme nos vemos
me parece que enseñarles un poco no esta mal
por q son tan tiernas q da ganas de chuparsela todita mandame fotos te intercambio
quiero que me manden fotos y videos de pornografia infantil porfisssssss a emma1870@hotmail.com
quiero que me mande paginas de niñas cogiendo a gato_76_2004@hotmail.com porfa

Bastante repugnante, la verdad. Si yo fuera Nacho mandaría las IPs a la policia aunque solo sea para que las investiguen.

En fin, si por casualidad google indexa esta página entre los primeros resultados para 'porno infantil', si quereis fotos de niños, solo teneis que entrar en http://www.mir.es/policia/index.htm y pulsar donde dice 'denuncias'. En pocas horas unos amables señores vestidos de azul llegarán a vuestra casa con todo el porno infantil que querais.

miércoles, julio 28, 2004

Instalador de plugins para Firefox

Doron Rosenberg, de doron's blaahg está escribiendo un wizard para firefox que ayude a instalar los plugins para los usuarios mas inexpertos. Podeis seguir su progreso en el bug 253046 de bugzilla y ver algunas capturas de pantalla en http://www.nexgenmedia.net/ff/screenshots/.

GmailerXP


GmailerXP pretende ser la única aplicación que necesites para manejar el correo de Gmail desde tu pc. Con ella se puede hacer todo lo que se puede hacer desde la página web de Gmail y además incluye las caraceterístitcas de otras aplicaciones como Gmail Loader o Gmailto.

La aplicación aún está en fase beta pero pueden ser descargadas compilaciones nightly desde su página web.

Javascript: Polimorfismo

La palabra polimorfismo se refiere al hecho de tener varios métodos con el mismo nombre y la misma implementación. En la programación orientada a objetos el polimorfismo a considerar es el polimorfismo de clases (también pueden implementar otros tipos pero no nos interesa ahora), que consiste en que un objeto de una clase derivada es al mismo tiempo un objeto de la clase padre, de forma que allí donde se utilice un objeto de la clase padre también se puede utilizar uno de la clase hija.

Por ejemplo si tenemos una clase instrumento de la que derivan guitarra y bajo; las guitarras y los bajos son instrumentos así que se puede asociar una referencia instrumento a un objeto de tipo guitarra, porque al fin y al cabo dado que guitarra tiene definidos todos los métodos y propiedades que tenía instrumento (porque los ha heredado) no nos dará ningún problema, lo único que puede cambiar es que se halla sobreescrito la implementación de alguna función.

Por ejemplo supongamos un método tocar en instrumento que imprime en pantalla "Toco un instrumento" y que se sobreescribió en la clase guitarra para que escribiera "Toco una guitarra". Si creamos un objeto de la clase guitarra pero la enlazamos a una referencia de la clase instrumento, entonces guitarra se comportará como un objeto de la clase instrumento, olvidando que tiene otros métodos y propiedades que no sean los que estaban definidos en la clase instrumento. Sin embargo si llamamos a la función tocar de este objeto, se imprimirá el mensaje "Toco una guitarra", en lugar de "Toco un instrumento". Polimorfismo.

Esto es posible gracias a que se ha utilizado un enlace dinámico o tardío, es decir, se asigna a cada una de las llamadas su implementación correspondiente en tiempo de ejecución, en lugar de hacerlo durante la compilación (enlace estático) que provocaría que quede fijado, con lo que en el ejemplo anterior al ver una referencia de tipo instrumento, la enlazaría con la implementación del método en instrumento, no en guitarra.

Dado que Javascript no tiene herencia basada en clases, muchas veces se considera equivocadamente que Javascript no soporta polimorfismo, porque se confunde polimorfismo con polimorfismo de clases. Vamos a ver un ejemplo. Supongamos una empresa dividida en departamentos, que a su vez puede estar dividida en otros subdepartamentos y así sucesivamente. Tenemos entonces un objeto departamento que a su vez puede incluir otros departamentos, que también pueden incluir otros,... El objetivo es calcular el sueldo total a pagar de todos los trabajadores. El sueldo de un departamento es la suma de todos los sueldos de los objetos que lo conforman, ya sean trabajadores u otros departamentos.

Para calcular el sueldo total de la empresa podríamos recorrer la matriz que representa la empresa comprobando si el objeto es un departamento o un empleado y llamando al método correspondiente según el tipo de objeto. Sin embargo, podemos aprovecharnos del polimorfismo. Si llamamos al método de la misma forma, por ejemplo calcularNomina, y recorremos el array llamando a calcularNomina para cada objeto, el intérprete se encargará de ver si la implementación que le corresponde es la de departamento o la de empleado:

<script>
function departamento(){
this.personal = new Array();
this.anyadir = anyadir;
this.calcularNomina = calcularNominaDept;
}

function empleado(nomina){
this.nomina = nomina;
this.calcularNomina = calcularNominaEmpl;
}

function anyadir(objeto){
this.personal.push(objeto);
}

function calcularNominaDept(){
var nomina = 0;
for(var i = 0; i < this.personal.length; i++){
nomina += this.personal[i].calcularNomina();
}
return nomina;
}

function calcularNominaEmpl(){
return this.nomina;
}

empresa = new departamento();
empresa.anyadir(new empleado(200));
empresa.anyadir(new empleado(100));
contabilidad = new departamento();
contabilidad.anyadir(new empleado(120));
empresa.anyadir(contabilidad);
document.write(empresa.calcularNomina());
</script>

En resumen, tenemos varios métodos con el mismo nombre y distinta implementación y el intérprete se encarga de decidir como enlazarlos según el caso.

martes, julio 27, 2004

Javascript: Encapsulación

La encapsulación se refiere a impedir el acceso a determinados métodos y propiedades de los objetos estableciendo así que métodos y propiedades de estos pueden ser utilizados desde el resto del código. Esto se consigue en otros lenguajes de programación utilizando modificadores de acceso, que definen si cualquiera puede acceder a esa función o variable (public) o si está restringido el acceso a la propia clase (private). Para acceder al valor de las variables private o modificar su valor se añaden también funciones cuyo único cometido es este, y a las que normalmente se les da el nombre de getVariable y setVariable.

En Javascript se carece de estos modificadores de acceso, de forma que nos valemos del ámbito de la variable (en que parte del programa puede ser accedida) para emularlo. Para establecer una variable como 'privada' usamos var para que sea local a la función constructora en lugar de hacer 'this.variable = ...'. Además tenemos que incluir las funciones get y set dentro de la misma función constructora ya que la variable es ahora local y si estas estuvieran fuera de la función constructora no podrían acceder a ella.

<script>
function objeto(){
var numero = 22;
var texto = "Hola";
this.setNumero = setNumero;
this.setTexto = setTexto;
this.getNumero = getNumero;
this.getTexto = getTexto;

function getNumero(){
return numero;
}

function getTexto(){
return texto;
}

function setNumero(nnumero){
numero = nnumero;
}

function setTexto(ntexto){
texto = ntexto;
}
}

var miObjeto = new objeto();

/*numero es local a objeto, por lo tanto esto daria error quejandose de que numero no esta definido*/
//document.write(numero);
/*como no hemos asociado numero al objeto con this.numero esto tampoco funciona y nos imprime undefined*/
document.write(miObjeto.numero + "<br/>");
//Esta es la forma correcta de acceder
document.write(miObjeto.getTexto() + "<br/>");
//y esta la de modificar su valor
miObjeto.setTexto("Adios");
document.write(miObjeto.getTexto());
</script>

WebLog Pinger

En Foxcorp he encontrado una pequeña aplicación (21KB) llamada Weblog Pinger y que como su nombre indica sirve para hacer ping a los sitios como bitacoras.net, bitacoras.com o weblogs.com que incluyen listas de las últimas bitacoras actualizadas.

No están todos los sitios a los que solía hacer ping (los de ping-o-matic además de bitacoras.com y .net) pero es mas comodo que andar de web en web.

Javascript: La herencia

Hay tres conceptos que son básicos para cualquier lenguaje de programación orientado a objetos: el encapsulamiento, la herencia y el polimorfismo. Aunque no estén soportados directamente por el lenguaje vamos a ver como podemos lograr estas tres cosas en Javascript. Empecemos por la herencia.

En un lenguaje orientado a objetos cuando establecemos que una clase (subclase) hereda de otra clase (superclase) estamos haciendo que la subclase contenga todas las propiedades y métodos que tenía la superclase.

Veamoslo con un ejemplo. Supongamos que queremos modelar los instrumentos musicales de una banda. Vamos a tener un tipo de objeto guitarra, otro tipo batería, bajo,... cada uno con sus propias propiedades y métodos, pero ocurre que puede que halla métodos y/o propiedades comunes a todos ellos por el hecho de ser instrumentos musicales, por ejemplo un método tocar. Podríamos crear un tipo de objeto instrumento que sería el que tuviera el método e indicar al programa que guitarra, batería y bajo son tipos de instrumentos, haciendo que hereden de instrumento y que obtengan todos sus propiedades y métodos (en este caso solo el método tocar).

En Javascript hay dos formas de implementar la herencia. La primera forma consiste en llamar al constructor del tipo padre dentro del constructor del tipo hijo. Abrimos el bloc de notas, escribimos lo siguiente y guardamos con extensión htm (no es un archivo html válido porque ni tan si quiera tenemos la etiqueta html o el body).

<script type="text/javascript">
//Constructores
function persona (nombre, dni){
this.nombre = nombre;
this.dni = dni;
this.toString = toString;
}

function alumno (nombre, dni, asignaturas){
this.heredar = persona;
this.heredar(nombre, dni);
this.asignaturas = asignaturas;
}

function profesor (nombre, dni, sueldo){
this.heredar = persona;
this.heredar(nombre, dni);
this.sueldo = sueldo;
}

//Otras funciones
function toString (){
return this.nombre + " " + this.dni;
}

//Inicio del programa
var pepe = new alumno("Pepe Botijos", 343234569, new Array("Matematicas", "Fisica", "Quimica"));
document.write(pepe.nombre + "<br/>");
document.write(pepe.dni + "<br/>");
document.write(pepe.asignaturas + "<br/>");
document.write(pepe.toString() + "<br/>");
</script>

En este ejemplo tenemos un tipo de objeto persona de la que heredan alumno y profesor (alumno y profesor son personas), por lo tanto estos dos subtipos tendrán las propiedades (nombre y dni) y los métodos (toString) que se hallan definido para el tipo persona, mas los que se definan en el subtipo (asignaturas en el caso del alumno y sueldo en el caso del profesor).

En este ejemplo hay un par de cosas que aún no habíamos visto, el hecho de que el operador + cuando actúa sobre cadenas, las concatena; y la función document.write que escribe un texto en el navegador. Además la palabra clave this, se refiere al objeto actual, de forma que this.toString() significa 'llama a la función toString del objeto actual' y this.sueldo significa la variable sueldo del objeto, en lugar de la variable sueldo que nos pasan como argumento.

La segunda forma de implementar la herencia se basa en la propiedad prototype, que existe por defecto para todos los objetos. Lo único que hay que hacer asignar a la propiedad prototype del tipo hijo el objeto padre.

function instrumento (){
this.tocar = tocar;
this.romper = romper;
}

function guitarra (){
}
guitarra.prototype = new instrumento();

function bateria (){
this.romper = romperBateria;
}
bateria.prototype = new instrumento();

function tocar (){
document.write("Estamos tocando musica<br/>");
}

function romper (){
document.write("Eso lo pagas tu<br/>");
}

function romperBateria (){
document.write("Rompiendo bateria, por favor espere.<br/>");
}

Esto funciona porque cuando se intenta acceder a una propiedad de un objeto, primero se comprueba si la propiedad existe entre las propiedades definidas para ese objeto. En el caso de que no se encuentre se comprueba si el objeto al que apunta la propiedad prototype tiene esa propiedad. En el caso de que este tampoco la tenga se comprueba para el objeto de la propiedad prototype de este y así sucesivamente (cada objeto tiene otro objeto que es su prototipo y hereda todas las propiedades de este).

Gravatares

Gravatar, el nuevo servicio ofrecido por Tom Werner y Rob Cameron puede parecer una tonteria a primera vista de simple que es :P pero es una buena idea :) .

Un gravatar es algo parecido a los avatares de los foros de discursión, una imagen que identifica al usuario. De esta forma cuando otro usuario te asocia con tu avatar no tiene que leer el nombre del usuario que ha escrito el post, sino que le basta con echar un vistazo a los avatares, lo cual mejora la palabra con U mayúscula, Usabilidad.

Un gravatar pretende ser el hermano pequeño de los avatares en la blogosfera, una simple imagen asociada con el usuario que escribe un comentario en un blog. ¿Y cual es la innovación y el servicio que ofrece esta gente? porque no sería dificil implementar el que el usuario pudiera añadir una imagen para identificarse. Bienvenido a los Globally Recognized Avatar o Gravatar, avatares globalmente reconocidos. Es decir, el objetivo de esta gente es que los bloggers utilicen el plugin para su cms proporcionado por ellos que hará que al lado del comentario se muestre el gravatar del usuario, pero el usuario no tendrá que añadir el avatar para cada blog que visite, si no que añade su gravatar en gravatar.com y el blog tomará la imagen desde allí.

En resumen, el usuario crea una cuenta en gravatar.com seleccionando una imagen como gravatar y dado que los gravatares se toman de un único servidor, el de gravatar.com, solo se tiene que registrar una vez, mostrandose su gravatar en todos los blogs que tengan activado este servicio.

Lástima que no se pueda utilizar con Blogger, aunque puede que tengamos una sorpresa dentro de poco tiempo porque están discutiendo con la gente de Blogger la posibilidad de añadirlo :) .


gravatares

lunes, julio 26, 2004

FolderBox y Command Prompt Explorer Bar

Un par de capturas de los programas FolderBox y Command Prompt Explorer Bar, que comente de pasada en la entrada sobre los reemplazos del explorador de windows para que se vea a que me estaba refiriendo.


FolderBox añade un panel a la parte inferior del explorador en el que podemos abrir otra carpeta, para ver el contenido de dos carpetas a la vez. Además permite tener hasta cinco carpetas abiertas (mostrando solo una, claro) usando pestañas. Existe una versión de pago con la que se pueden abrir hasta 10 ventanas y que añade un botón a la barra de menús para abrir el programa mas rapidamente.


Command Prompt Explorer Bar añade un panel con una línea de comandos al explorador. Pero es mucho mas que una simple ventana de cmd.exe, ya que esta consola cambia automáticamente de directorio cuando nos desplazamos en el explorador de windows y añade una barra de menús a la izquierda con diferentes comandos para mejorar nuestra productividad.

Extensiones

Un par de extensiones interesantes vía My Extensions Mirror:

FeedBurner

Acabo de crear una cuenta en FeedBurner para mejorar el feed Atom que proporciona Blogger. Entre otras cosas Feed Burner permite (estas son las opciones que yo he elegido):

  • SmartFeed: En caso de que alguien se intente suscribir a tu feed con un lector de feeds que no soporte el formato de tu feed, FeedBurner lo convierte a un formato que si reconozca automáticamente.
  • El feed tendrá un icono asociado.
  • Si se intenta ver el feed desde un navegador en lugar de mostrar un montón de código XML sin sentido, el usuario verá un preview del feed.
  • Estadísticas sobre el uso de tu feed.

Además una vez creado el nuevo feed mejorado, te dan varias opciones de como se verá el enlace al feed en tu página web. En lugar de la simple imagen indicando el formato del feed o de un simple texto del tipo 'Sindica este sitio' puedes usar por ejemplo su Headline Animator, una imagen gif que muestra los títulos de las últimas entradas de tu bitacora.

Zootropo

Reemplazos del explorador de Windows

Ayer estuve probando unos cuantos programas para reemplazar el explorador de Windows. Entre ellos los mas destacados:

  • xplorer2: vista con dos paneles para ver el contenido de dos carpetas a la vez. Nos permite también escribir comandos MS-DOS. La versión completa es de pago, pero existe una versión gratuita para uso no comercial.
  • ExplorerXP gratuito, permite navegación con pestañas.
  • Magellan Explorer
  • Total Commander: parece el mas completo de todos pero tiene un look a lo Windows 3.11 insoportable.

Las características mas destacadas que ofrecen respecto del explorador de Windows son la posibilidad de dividir el explorador en dos paneles para ver dos carpetas a la vez, pero también puede hacerse con el explorador de Windows usando FolderBox; y escribir comandos MS-DOS para tareas de gestión de los archivos mas complejas, cosa que también se puede hacer con el navegador de Windows gracias a Command Prompt Explorer Bar que permite crear un panel con una línea de comandos en la ventana del explorador.

Contra los problemas DNS: DNSLint

DNSLint es una utilidad de Microsoft que ayuda que diagnosticar los problemas habituales de resolución de nombres DNS.

El programa puede ser descargado desde la web de Microsoft. Una descripción del funcionamiento del programa se puede encontrar en la Microsoft Knowledge Base

sábado, julio 24, 2004

Javascript: Funciones. Orden superior

Una función se define en javascript mediante la palabra clave function seguida del nombre de la función y de los argumentos de esta entre paréntesis y separados por comas.

function nombre (argumentos) {

cuerpo de la funcion
}

Para devolver el valor de retorno de la función se utiliza la palabra clave return. Como vemos no difiere mucho de las funciones de otros lenguajes de programación.

function multiplica (x, y) {

return x * y;
}

Una vez que la función ha sido definida puede llamarse desde cualquier punto del programa pasándole los argumentos correspondientes:

//miVar toma como valor el producto de 3 por 2, 6
var miVar = multiplica(3,2);
//ahora miVar vale 60
miVar = multiplica(miVar,10);

Nada perturbador de momento. Veamos ahora las características funcionales de javascript. Para ello vamos a usar una construcción típica en los lenguajes funcionales como es la función recursiva map. map recorre una matriz aplicando una función a cada uno de los elementos de la matriz.

function map (funcion,matriz) {
if (matriz.length==0)
return matriz;
else {
return new Array().concat(car = funcion(matriz.shift())).concat(map(funcion,matriz));
}
}
function cuadrado (x) {
return x * x;
}
var miArray = new Array(1,2,3,4,5,6);
/*map devolvera una matriz cuyos elementos son el cuadrado de los elementos de miArray*/
var resultado = map(cuadrado,miArray);

Este programa hace uso de las funciones de orden superior para recorrer una lista de valores y aplicar la función cuadrado a cada uno de los valores. El funcionamiento en si de map no nos importa demasiado ahora mismo, no tiene que ver con el lenguaje, pero lo explicaré de todas formas para que se vea mas claramente.

La función recursiva map funciona tomando en cada paso el primer elemento de la matriz y aplicando la función que nos pasan como argumento a ese elemento. Después se toma el nuevo elemento en la cabecera de la matriz, que ahora será el que era segundo elemento antes, volviendo quitar este del array y a aplicar la función sobre este. El proceso se repite hasta que el array este vacio, momento en que se vuelve atras en la recursión y se va añadiendo a la izquierda los elementos que se transformaron con la función pasada como argumento.

Ahora bien, lo que de verdad nos interesa de este ejemplo es que le estamos pasando una función como argumento a map. Las funciones son valores normales, que pueden ser pasados como argumentos o ser el valor de retorno de una función y que pueden ser también guardados en variables. Veamos un ejemplo mas sencillo que ilustre esto.

function componer (f, g, x) {

return f(g(x));
}

Este es un ejemplo bastante tonto y sin utilidad pero ya hemos visto con map las posibilidades que nos dan las funciones de orden superior.

Veamos ahora como un ejemplo en el que devolvemos una función:

function operar (operacion) {
switch (operacion){
case "rep":
return reponer;
case "ven":
return vender;
}
}

function reponer (cantidad) {
dinero = dinero - (cantidad * 5);
unidades = unidades + cantidad;
}

function vender (cantidad) {
dinero = dinero + (cantidad * 10);
unidades = unidades - cantidad;
}

var dinero = 1000;
var unidades = 100;
//Ahora tenemos 990 euros y 102 unidades
operar("rep")(2);
//y despues de vender 50, 1490 euros y 52 unidades
operar("ven")(50);

Si llamamos a la función operar con "rep" como argumento nos devuelve la función reponer, de forma que operar("rep")(2) es equivalente a llamar directamente a reponer(2) e igualmente al pasar como argumento "ven", se nos devuelve la función vender, con lo que operar("ven")(50) es equivalente a vender(50).

Javascript: Matrices

Un array o matriz es una estructura de datos que almacena una serie de elementos (que no tienen porque ser del mismo tipo, en Java por ejemplo si) a los que se accede atraves de un número que indica su posición en la matriz que se conoce con el nombre de índice.

Las matrices en Javascript son objetos de tipo Array, por lo tanto se crean usando el constructor Array():

//creamos una matriz vacia
a = new Array();
//también podemos crear una matriz vacia pero reservar espacio para n elementos
b = new Array(10);
//o especificar sus elementos a la hora de crear el array
personajes = new Array("Ricenwind","Mort","Tata Ogg");

Además las matrices no son estáticas, una vez creadas podemos cambiar los elementos que contiene así como acceder a los elementos de cualquier posición, ambas cosas gracias al operador [].

/*Obtenemos el valor del primer elemento de la matriz y lo metemos en la variable protagonista*/
var protagonista = personajes[0];
/*Para modificar o añadir valores se usa también []*/
personajes[3] = "La Muerte";

Es importante darse cuenta de que el primer elemento de la matriz tiene como índice 0, no 1, como sucede en Java o C++.

Ahora, recordando lo que vimos sobre los objetos y sabiendo que las matrices son objetos, es razonable suponer que el objeto Array tendrá propiedades y métodos que nos ayuden a la hora de programar. Vamos a ver los mas interesantes.

Propiedades

  • length: contiene el tamaño de la matriz.
    /*Tenemos 4 elementos en personajes, por lo tanto el tamaño de la matriz es 4*/
    tamanyo = personajes.length;

Métodos

  • concat: devuelve el resultado de concatenar las matrices que se pasan como argumento a la matriz sobre el que se llama, sin afectar a ninguna de las matrices involucradas.
    /*ahora tendriamos la matriz que tiene como elementos los elementos de personajes dos veces*/
    var personajes = personajes.concat(personajes);
  • pop: retira el el primer elemento de la matriz y devuelve este como valor de retorno.
    /*ultimo contendria "La Muerte" y personajes pasaria a ser la matriz con los elementos que tenía antes menos el último elemento*/
    var ultimo = personajes.pop();
  • push: añade los elementos que se pasan como argumento a la función a la matriz.
    /*Ahora personajes contiene al final de la matriz los numeros 1,2 y 3*/
    personajes.push(1,2,3);
  • shift: similar a pop, pero en este caso elimina y devuelve el primer elemento de la matriz, no el último.
  • toString: devuelve la representación de la matriz como una cadena de texto.
    /*cadena contendría "Rincewind, Mort, Tata Ogg, La Muerte, Rincewind, Mort, Tata Ogg, 1, 2, 3"*/
    var cadena = personajes.toString();

Javascript: Objetos

Un objeto agrupa variables referidas a ese objeto, llamadas propiedades y funciones (las funciones las veremos después, si no sabes que es una función olvidalo por ahora) asociadas al objeto y que manipulan sus variables, llamadas métodos. Por ejemplo un objeto coche podría tener como propiedades su marca, el número de puertas, el tipo de carburante,... y como métodos arrancar, parar,...

En lenguajes de programación mas orientados a objetos, como Java, además de los objetos tenemos lo que se llaman clases que definen que propiedades y métodos tienen los objetos de esa clase y apartir de las cuales instanciamos los objetos. Un ejemplo sería una clase coche; en la vida real hay un conjunto de objetos a los que llamamos coches y que tienen un conjunto de propiedades comunes, esto es lo que se llamaría la clase. Sin embargo, mi coche no es igual que el coche de mi vecino, pertenecen a la misma clase (ambos tienen propiedades como la marca, el número de caballos,... y métodos comunes como arrancar, parar,...) pero son objetos distintos. En Javascript como hemos dicho, no existen las clases (aunque en algunos sitios se les llama de forma incorrecta clases al tipo del objeto, lo cual puede ser confuso), de forma que al crear un objeto no se está instanciando una clase, como ocurre en Java. Al crear objetos en Javascript, no tenemos un molde del que sacar los objetos, que sería la clase.

Para crear un objeto en Javascript se puede utilizar una función que se encargue de inicializar las variables y esa clase de cosas, a la que se llama constructor. El nombre de esta función será el que se le dé al tipo de objeto resultante:

/*creamos objetos utilizando el operador new que llama al constructor*/
var miPc = new PC();
/*el constructor es una función como cualquier otra y puede tener argumentos*/
var miCPU = new CPU("AMD","Athlon",1400);

Otra forma de crear un objeto, menos intuitiva para programadores Java son los inicializadores, que es parecido a definir una función constructor pero en la que solo se va a asignar valores a variables y nada mas. La sintaxis es la siguiente:

nombreObjeto = {propiedad1:valor1, propiedad2:valor2, ..., propiedadN:valorN};

Además los inicializadores se pueden anidar, creando objetos como propiedades de otros objetos:

pc = {cpu:{fabricante:"AMD", modelo:"Athlon", velocidad:1400}, memoria:512, MB:Asus 7532"};

Una vez creado el objeto para acceder a las propiedades o los métodos de un objeto se utiliza el operador punto (.), y usamos el mismo procedimiento al asignar un valor a estos. Dado que Javascript declara directamente las nuevas variables al asignarlas un valor si estas no estaban antes declaradas nos basta dar un valor a una variable de un objeto para definir una nueva propiedad del objeto (para definir un nuevo método también basta hacer algo del tipo objeto.nombreMetodo = nombreFuncion;). Además conviene hacer notar que dado que los objetos también son datos, pueden definirse como propiedades de otro objeto. Veamos un ejemplo de todo esto.

/*Accedemos a la propiedad fabricante de mi objeto fabricante, que habremos asociado previamente con el valor que nos pasaron como parámetro al crear el objeto en nuestro constructor. Ahora fab contiene la cadena "AMD"*/
var fab = miCPU.fabricante;
/*También podemos cambiar el valor de una propiedad de la misma forma*/
miCPU.fabricante = "Intel";
/*o definir nuevas propiedades*/
miCPU.precio = 120;
/*y como ya hemos mencionado, establecer un objeto como propiedad de otro objeto*/
miPC.cpu = miCPU;
/*para acceder a una propiedad de un objeto que sea a su vez propiedad de otro objeto utilizamos también el operador punto*/
var precio = miPC.miCPU.precio;

document.all en Mozilla/Firefox

Las proximas versiones de Mozilla y Firefox soportarán la colección propietaria de IE document.all, el equivalente a la estándar document.getElementById, lo que provocará que alguno de los sitios que no funcionaban con Firefox ahora si funcionen.

Sin embargo si se comprueba la presencia de la propiedad

if (document.all)

alert("Existe la propiedad");

la comprobación devolverá false, es decir, se añade el soporte a document.all pero no es detectable, de forma que solo se utilizará si el desarrollador no fue lo bastante inteligente para comprobar antes si existía soporte para document.all en el navegador del usuario, dando por supuesto que el usuario utilizaba IE como navegador.

Esto es así porque si se comprobó si existía document.all, el código debería comprobar también si existe soporte para getElementById, de forma que se ejecutaría el código correspondiente al segundo y no se afectaría a los estándares.

This Page Intentionally Left Blank

Nuevas características en Thunderbird 0.8

En Redemption in a Blog publican hoy un review del nuevo Mozilla Thunderbird 0.8 que se espera para dentro de poco, con un repaso imagen a imagen de las nuevas características. Entre lo mas destacado tenemos:

  • Integración RSS y Atom (aún no se puede probar en las últimas compilaciones pero se supone que funcionará de manera similar a la extensión Forumzilla, ya que la mayor parte del código está tomado de esta)
  • Las imagenes de los correos se bloquearán por defecto (tipo Gmail) de forma que no avises involuntariamente a los spammers de que tu cuenta de correo está activa
  • Cuando se añade una nueva cuenta POP3 ahora existe la posibilidad de tener un solo conjunto de carpetas para todas las cuentas
  • Se ha añadido una nueva opción para descargar el correo de todas las cuentas
  • Se ha modificado algo la barra de búsqueda. Ahora nos permite seleccionar en que campos se quiere buscar

viernes, julio 23, 2004

Vacas del Universo

La verdad es que no se porque estoy escribiendo un post para comentar una página en la que solo hay cuatro imagenes y nada mas. Pero me han encantado las imagenes y ya tengo una puesta como wallpaper. El sitio en cuestión es Cows of the Universe (Vacas del Universo).

Tiene tan poco sentido como este post.

The cows munch grass, they do this a lot, a simple life one might say.. but there is always the danger, NINJAS

Bill Withers

Bill Withers es uno de esos famosos desconocidos de la música, el tipo de artista del que todos conocemos alguna de sus canciones pero que al ver su nombre simplemente no los relacionas.

Withers es uno de los grandes de la música negra con éxitos como 'Ain't no Sunshine', su primer hit con el que ganó su primer gramy en 1971 y que ha sido versionado entre otros por gente como Sting, Michael Bolton o The Temptations y que ha sido incluida en películas como Notting hill o 'Just the Two of Us' por la que ganó un gramy en 1981 y fue nominado a otros tres por la misma canción ese año y que ha sido versionada entre otros por Will Smith.

Otras canciones recomendables de Bill Withers son 'Lean on Me', 'Use Me Up' o 'Lovely Day'.

Y otra invitación de Gmail

AlmaOscura de AfterDusk comenta hoy la escasez de invitaciones de Gmail que se está dando ultimamente. Como yo soy mas chulo que nadie regalo una invitación al primero que pueda decirme como se llama el grupo del protagonista de la película 'School of Rock'. Y me refiero al grupo de rock que tiene en la vida real, no a como se llamaba el grupo de la película 8-)

Ala, poneos las pilas que según la ley de la oferta y la demanda ahora debería estar muy cotizada :P

Javascript: Incluyendo el código javascript en documentos html

El código javascript puede ejecutarse en el pc del cliente o en el servidor. Hay dos formas de incluir un código Javascript en una página web de forma que el código se ejecute en el pc del cliente através de su navegador, embebido dentro de la propia página web o escribirlo en un archivo .js aparte e importarlo después. Usando la primera forma tendríamos un código parecido a este dentro de nuestro documento html:

<script language="javascript" type="text/javascript">
<!--

codigo javascript

// -->
</script>

Como vemos el código javascript se incluye dentro de una etiqueta de html llamada script con atributos language, que define que lenguaje de script estamos utilizando (y también la versión si queremos, aunque no es aconsejable ya que puede dar problemas) y type, que define el tipo MIME. language y type tienen la misma función, identificar que tipo de script vamos a escribir, de forma que no es necesario escribir ambos. En principio si solo queremos escribir uno de ellos es recomendable utilizar type, ya que es el estándar según la W3C, aunque no está de mas escribir ambos por los navegadores antiguos.

Es aconsejable que el código javascript se incluya dentro de un comentario html (entre <!-- y -->) de forma que los navegadores antiguos que no reconocen la etiqueta script no impriman el código javascript como texto de la página web. Además tenemos que añadir // que se utiliza como un comentario de una sola línea en javascript (para comentarios de varias líneas se utiliza /* mi comentario */ como en Java o C++) antes del --> ya que javascript reconoce <!-- como un comentario de una sola línea al igual que //, pero no ocurre así con -->. Finalmente cerramos la etiqueta con </script>.

La otra forma de incluir el código javascript que comentamos, el de importar el archivo js tiene como ventajas la claridad al separar html y el código además de mejora en la rapidez de carga de la página, ya que el navegador normalmente añadirá el archivo js a la caché. Para incluir el código de esta forma utilizamos el atributo src (de source, fuente) de la etiqueta script con el que indicamos la url del archivo javascript:

<script src="http://zootropo.blogspot.com/miarchivo.js">
</script>

Una última cosa a comentar al respecto es el uso de la etiqueta <noscript> que incluye contenido que se mostrará a los navegadores que no soporten javascript o en los que se halla desactivado javascript.

<script>
codigo javascript
</script>

<noscript>
Su navegador no soporta Javascript
</noscript>

jueves, julio 22, 2004

Javascript: Control de Flujo

Condicionales
if (condicion) {

expr1;
}
else {
expr2;
}

En el caso de que condición sea cierto se evalua expr1, en caso contrario expr2.

switch (expresion){

case valor1 :
expr1;
break;
case valor2 :
expr2;
break;
...
default : exprN;
}

Si expresión evalua a valor1 se ejecuta expr1, si evalua a valor2 se evalua expr2,... default se ejecuta si no evalúa a ninguno de los demás. break hace que salgamos del switch, es similar en su uso a Java o C++. Además tenemos tamién el continue de Java que hace que pasemos a la siguiente iteracción del bucle.

Bucles
for (inicializacion; condicion; incremento) {
exprs
}

Antes de comenzar el bucle se ejecuta la expresión definida en inicializacion (normalmente la definición de una variable que será el índice del bucle). Mientras se cumpla condicion se evalúan las expresiones exprs y al final del bucle se ejecuta incremento.

while (condicion) {

exprs
}

Mientras condicion sea cierta se evalúan las expresiones exprs.

do {

exprs
} while (condicion);

Similar a while pero como la condición se comprueba al final del bucle exprs siempre se ejecutarán al menos una vez.

for (variable in objeto) {

exprs
}

En cada paso del bucle se asigna como valor a variable la siguiente propiedad de objeto. Por ejemplo si objeto fuera una matriz con los días de la semana variable valdría primero lunes, luego martes,... Es similar al for-in de Perl.

Javascript: Operadores Básicos

Los operadores en Javascript son similares a los de sus primos mayores Java o C++, por lo tanto solo los comentaré de pasada.

Operadores Aritméticos

OperadorSignificado
+Suma
-Resta
*Multiplicación
/División
%Módulo
++Incremento
--Decremento
-Negación (unario)

Todos los operadores son binarios (se aplican sobre dos argumentos) menos los tres últimos. La operación de módulo a % b devolvería el resto resultante de dividir a entre b. El incremento y decremento suman o restan la unidad al operando sobre el que se aplica y tienen diferente efecto dependiendo de si se coloca antes o después del operando, tal como ocurre en Java o C++, en el caso de que se coloque ante del operando primero se sumará/restará la unidad y luego se evaluará la expresión y en caso de que se coloque después del operando ocurrirá al reves.

Además de estos operadores existen otras funciones del objeto Math que definen funciones matemáticas clásicas como el seno, el coseno o la raíz cuadrada.

Operadores Relacionales

OperadorSignificado
==Devuelve true si los dos operandos son iguales (si son de distinto tipo se hace una conversión primero)
===Devuelve true si los dos operandos son iguales y son del mismo tipo
!=Devuelve false si los dos operandos son iguales (si son de distinto tipo se hace una conversión primero)
!==Devuelve true si los dos operandos son iguales y son del mismo tipo
>Mayor que
>=Mayor o igual que
<Menor que
<=Menor o igual que

Aquí hay que notar que las comparaciones de igualdad entre objetos se realizan por referencia, es decir, se compara si los dos objetos son exactamente el mismo objeto (si tienen la misma dirección en memoria) no si representan el mismo valor.

Operadores Condicionales

OperadorSignificado
&&And (devuelve true si ambos operandos evalúan a true)
||Or (Devuelve true si alguno de los operandos evalúa a true)
!Not (unario, devuelve true si la expresión evalúa a false)

Operadores a nivel de bit

OperadorSignificado
&And
|Or
^Xor
~Not
<<Desplazamiento a la izquierda
>>Desplazamiento a la derecha
>>>Desplazamiento a la derecha (sin signo)

Los operadores de desplazamiento desplazan a derecha o izquierda el número de bits indicado por el segundo operando

Además de todos estos operadores tenemos los operadores de asignación, que realizan una asignación y una operación con un solo operador. Por ejemplo el operador += asigna como valor al primer operando el valor que se obtiene de sumar el primer y el segundo operando, entonces la expresión a += b; sería equivalente a a = a + b;. Existe un operador de asignación para cada uno de los operadores aritméticos y operadores a nivel de bit.

Javascript: Variables, Constantes y Tipos de Datos

Tenemos como tipos de datos básicos los números (como 3 o 15.57), las cadenas (como "Hola Mundo") y los valores booleanos (true, cierto o false, falso) además de el valor especial null, que indica un valor nulo y undefined, que indica que no se definió ningún valor para la variable.

Además de los tipos de datos básicos tenemos las matrices, matrices asociativas (hashes, se accede a una posición de la matriz atraves de una cadena llamada su clave en lugar de un número índice que indica su posición en la matriz) y las funciones y los objetos, que funcionan como una especie de matrices asociativas.

En Javascript, al igual que ocurre en otros lenguajes como Lisp, la definición de los tipos de los datos se hace de forma dinámica, es decir, una variable no está limitada a contener el tipo de dato que se indicó al declarar la variable, sino que puede contener primero un número y mas tarde pasar a contener una cadena de texto, por ejemplo. De hecho en Javascript al declarar las variables (con la palabra clave var) no se define un tipo para esa variable. Por ejemplo en Java o C++ para declarar e inicializar variables haríamos algo parecido a esto:

int miNumero=7;
String miCadena="Hola Mundo";

es decir, indicamos el tipo de la variable, el nombre y su valor. Sin embargo en Javascript se usaría:

var miVariable=7;
miVariable="Hola Mundo";

indicando simplemente el nombre y el valor de inicio, sin necesidad de especificar el tipo de la variable. O incluso podríamos prescindir de declarar la variable, ya que si al intentar asignar un valor a una variable Javascript comprueba que esta no ha sido declarada la declara automáticamente:

miNumero=7;
miCadena="Hola Mundo";

Por último, en Javascript también se pueden declarar constantes como en C++ o Java mediante la palabra clave const

const pi = 3.14159;

¿Qué es Javascript?

Javascript es un lenguaje de scripts multiplataforma creado por Netscape actualmente en su versión 1.5, totalmente compatible con ECMA-262, Edición 3. Contrariamente a lo que nos podría hacer suponer su nombre, no tiene nada que ver con Java, o al menos tiene tanto que ver como lo tiene por ejemplo con C++, ya que la sintaxis de los tres es parecida y tienen en común cosas como los bucles o estructuras de control. De hecho en principio el nuevo lenguaje se bautizó como Livescript pero se cambió su nombre a Javascript por cuestiones de marketing.

Javascript permite tanto programación imperativa como funcional, ya que incluye características de los lenguajes funcionales como las funciones de orden superior (high order programming, el uso de funciones como si de otro valor se tratara, posibilitando el pasar funciones como argumento a otras funciones o devolver funciones como valor de retorno) o las funciones lambda (funciones anónimas), por lo tanto está tan próximo a Java como lo está de leguajes funcionales como Lisp o Scheme. Así mismo permite tanto programación procedural como orientada a objetos, aunque no incluye características de lenguajes mas puros en su orientación a objetos como Java o Smalltalk como pueden ser las clases o la herencia.

Firefox Rama 21 Julio 2004

  • 238331 El tooltip del botón Clean Up debería decir "and" (y), no "or" (o) [Todos]
  • 246500 El tooltip del botón Use Theme del gestor de temas acaba con un punto a diferencia de los demas tooltips [Windows]
  • 251248 La entrada de menú "New Message..." no muestra el atajo asociado, Ctrl+M [Windows]
  • 251258 Tools->Read Mail no muestra el contador de mensajes no leidos cuando el icono de correo no esta en la barra de herramientas [Windows]
  • 251767 El atajo Ctrl+Shift+I para el DOM Inspector no se muestra en el menú [Windows]
  • 76525 El árbol en el diálogo de marcadores no debería mostrar el icono de que es expandible para las carpetas vacías [Todos]
  • 237766 la imagen de fondo se pinta dos veces al quitar el puntero de un enlace.[Windows]
  • 246754 Los enlaces que deberían instalar un tema automaticamente no funcionan al usar redirecciones HTTP.
  • 247960 Los dos paneles del administrador de marcadores no interactúan [Windows].(parche revisándose)
  • 249004 Sobreescribir el certificado incorporado en Firefox conduce al error -8182 (DoS), explotable via correos electrónicos [Todos] (Parche en super revisión)
  • 134260 [meta] Cambio de tema dinámico (cambiar skin) [Todos]
  • 225281 en la ventana del instalador que informa de que se completó la instalación el fondo de "Install Complete" debería ser blanco, como el resto del marco
  • 245327 cambiar de tema hace que se borren todas las pestañas, se deshabilite su historial y no se puedan cerrar estas pestañas [Todos].(parche listo)
  • 246078 URLs de otras aplicaciones hacen que se abran dos ventanas de Firefox o una venatana y un diálogo de error [Windows].(ver comentario #26)
  • 248423 config.trim_on_minimize ya no funciona [Windows].(parche en revisión)
  • 250411 La barra de búsqueda aparece cuando se utiliza Midas, haciendo que no se pueda utilizar la barra espaciadora y la tecla de borrado [Win]
  • 251421 El nuevo control de popups no funciona correctamente [Windows]
  • 251802 Refresh Livemark no funciona desde la barra de herramientas de marcadores o desde el menú de marcadores [Todos]
  • 251891 Desde que se implementó la barra de búsqueda, FAYT no funciona con caracteres internacionales (no ASCII) [Todos]
  • 251988 El botón RSS no funciona en una página que contenga un RSS si la última página que visité no tenía RSS e hice click de todas formas sobre "page has no feeds for Livemark" [Windows]
  • 252288 los favicons de los marcadores aún no funcionan [Windows]
  • 252412 un livemark en una carpeta de marcadores hace que la carpeta se colapse la primera vez que se abre [Windows]
Version Windows Instalador de Windows
Versión Linux Instalador de Linux
Versión Mac no disponible

Nuevo ClearType en Windows Longhorn

Cuando la gente de Microsoft hace las cosas bien también se admite. Ian Griffiths habla hoy sobre la nueva implementación de Clear Type en Windows Longhorn comparada con la implementación en Windows XP sobre el que ha mejorado bastante.

El problema es que ClearType no produce ninguna mejora en el texto verticalmente, sino que incrementa la resolución horizontal en un factor de 3. En la última compilación de Longhorn, sin embargo, Microsoft añadide además antialiasing, que disimula los bordes pronunciados que tenían los textos con ClearType en XP.

Podeis ver un ejemplo en esta imagen del blog de Ian Griffiths, en la que se muestra una letra O con la fuente Arial con el ClearType de XP, con una implementación alternativa ideada por Ian llamada IanType y en el nuevo Longhorn. En la imagen correspondiente a XP se ven claramente bordes de sierra en la parte superior e inferior lo cual no ocurre en Longhorn.

Secure Shell Filesystem (Shfs)

Si usas Linux como sistema operativo y utilizas ssh para acceder a tus archivos en otros PCs puede resultarte util este programa.

Shfs es un módulo para el kernel de Linux que nos permite montar el sistema de archivos remoto vía ssh como si fueran archivos locales.

Puedes compilar tu mismo el código fuente o utilizar los rpm creados por Oliver Aaltonen.

miércoles, julio 21, 2004

Stumble Upon

Entre las muchas formas de matar el tiempo cuando te aburres está la de la busca y captura de sitios web interesantes utilizando Stumble Upon, una barra que se añade al navegador y con la que se puede puntuar sitios web y encontrar sitios que le gustaron a gente con tus mismos intereses.

La idea no es nueva, y Stumble Upon tampoco (llevan funcionando sobre un par de años) pero se me ha ocurrido comentarlo en un momento de aburrimiento por si alguien no lo conocía.

Es entretenido para pasar una tarde si tu novia y/o amig@s tienen cosas mejores que hacer que perder el tiempo contigo (joder que triste, ¿no? ¿has considerado el suicidio?) y no echan nada en la televisión. Además la gente de Stumble Upon se preocupó de crear una versión para Firefox/Mozilla/Netscape, no como la gente de Google con su Google Toolbar ¬¬.

Web de la semana: La Zona Oscura

La Zona Oscura
La Zona Oscura

El Service Pack 2 de Microsoft limitará el número máximo de conexiones

La última idea brillante de Bill Gates y sus chicos consiste en que el Service Pack 2 para Windows XP limitará el número máximo de conexiones por segundo, según ellos para reducir las posibilidades de distribución de los virus.

Según Microsoft, están trabajando para que esta nueva característica no interfiera con el funcionamiento normal de aplicaciones legítimas, pero por ahora la gente con el SP2 instalado tiene problemas al utilizar programas del tipo eMule que utiliza multitud de conexiones para buscar nuevas fuentes. Habrá que ver que considera esta gente aplicaciones legítimas, y si utilizarán esto para evitar la distribución de los virus o tamién contra los programas P2P 8-)

Firefox Compilación de Rama 20 Julio 2004

  • 243931 compilación GTK2 en AIX: el cursor no se sitúa en la posición correcta al insertar texto RTL (de idiomas en que se escribe de derecha a izquierda) en un texto LTR (idiomas en los que se escribe de izquierda a derecha) [AIX]
  • 76525 El árbol en el diálogo de marcadores no debería mostrar el icono de que es expandible para las carpetas vacías [Todos]
  • 237766 la imagen de fondo se pinta dos veces al quitar el puntero de un enlace.[Windows]
  • 246754 Los enlaces que deberían instalar un tema automaticamente no funcionan al usar redirecciones HTTP.
  • 247960 Los dos paneles del administrador de marcadores no interactúan [Windows].(parche revisándose)
  • 249004 Sobreescribir el certificado incorporado en Firefox conduce al error -8182 (DoS), explotable via correos electrónicos [Todos] (Parche revisándose)
  • 134260 [meta] Cambio de tema dinámico (cambiar skin) [Todos]
  • 225281 en la ventana del instalador que informa de que se completó la instalación el fondo de "Install Complete" debería ser blanco, como el resto del marco
  • 245327 cambiar de tema hace que se borren todas las pestañas, se deshabilite su historial y no se puedan cerrar estas pestañas [Todos].(parche listo)
  • 246078 URLs de otras aplicaciones hacen que se abran dos ventanas de Firefox o una venatana y un diálogo de error [Windows].(ver comentario #26)
  • 248423 config.trim_on_minimize ya no funciona [Windows].(parche en revisión)
  • 250411 La barra de búsqueda aparece cuando se utiliza Midas, haciendo que no se pueda utilizar la barra espaciadora y la tecla de borrado [Win]
  • 251421 El nuevo control de popups no funciona correctamente [Windows]
  • 251891 Desde que se implementó la barra de búsqueda, FAYT no funciona con caracteres internacionales (no ASCII) [Todos]

Version Zip Windows Instalador de Windows
Versión Linux
Versión Mac

martes, julio 20, 2004

Firefox Rama 19 Julio

  • 229503 no se pueden cambiar las opciones de auto detección en el menú view->character encoding al examinar el código fuente de una página [Windows]
  • 250104 Actualizada la documentación de ayuda para Firefox 1.0 [Windows]
  • 251165 La tecla F1 en Windows/*nix, y la tecla de ayuda de Mac ahora muestran la ayuda de Firefox al ser pulsadas [Todos]
  • 251846 Arreglados About:, Help->About y Help->Release Notes que muestran información sobre la versión y el cuadro de diálogo Acerca de [Todos]
  • 251906 Arreglado el error en el instalador de Windows Error occurred during installation - US Region Pack: -208 INVALID_ARGUMENTS [Windows]
  • 252063 No se puede iniciar Firefox [Todos]
  • 252006 Si la url del favicon de una página cambia no se muestra la imagen del favicon, ni tan siquiera la imagen por defecto [Linux]
  • 252077 Arreglado el error introducido al corregir el bug 240485 [Todos]
  • 76525 El árbol en el diálogo de marcadores no debería mostrar el icono de que es expandible para las carpetas vacías [Todos]
  • 237766 la imagen de fondo se pinta dos veces al quitar el puntero de un enlace.[Windows]
  • 246754 Los enlaces que deberían instalar un tema automaticamente no funcionan al usar redirecciones HTTP.
  • 247960 Los dos paneles del administrador de marcadores no interactúan [Windows].(parche revisándose)
  • 249004 Sobreescribir el certificado incorporado en Firefox conduce al error -8182 (DoS), explotable via correos electrónicos [Todos] (Parche revisándose)
  • 134260 [meta] Cambio de tema dinámico (cambiar skin) [Todos]
  • 225281 en la ventana del instalador que informa de que se completó la instalación el fondo de "Install Complete" debería ser blanco, como el resto del marco
  • 245327 cambiar de tema hace que se borren todas las pestañas, se deshabilite su historial y no se puedan cerrar estas pestañas [Todos].(parche listo)
  • 246078 URLs de otras aplicaciones hacen que se abran dos ventanas de Firefox o una venatana y un diálogo de error [Windows].(ver comentario #26)
  • 248423 config.trim_on_minimize ya no funciona [Windows].(parche en revisión)
  • 251421 El nuevo control de popups no funciona correctamente [Windows]
  • 251891 Desde que se implementó la barra de búsqueda, FAYT no funciona con caracteres internacionales (no ASCII) [Todos]
Version Zip Windows Instalador de Windows
Versión Linux no disponible
Versión Mac

Como asociar programas de correo diferentes para usuarios diferentes en XP

Seguramente a mas de uno le habrá pasado el que dos usuarios del mismo PC quieran tener como programa de correo por defecto dos programas diferentes. El problema es que en XP esto no se puede hacer ya que la opción de programa de correo por defecto no esta asociado con el usuario, solo puede existir un programa por defecto para todos los usuarios. Aunque se puede cambiar el enlace de correo electrónico del menú de inicio según el usuario, no se puede asociar programas de correo diferentes para usuarios diferentes, sino que si un usuario con privilegios de administrador establece un programa de correo como el programa por defecto este se asociará a todos los usuarios. Asi mismo, si el usuario no tiene privilegios de administrador el cambio simplemente no tendrá lugar. Esto se describe en el artículo 315240 de la Microsoft Knowledge Base.

Para resolver este problema se puede utilizar una aplicación llamada DefaultMail que solo ocupa 11KB y del que podeis ver una imagen aquí y que hará que se abra el programa especificado al pulsar sobre enlaces mailto, cuando lo indiquen programas que usen llamadas MAPI (Messaging Application Programming Interface) o al pulsar sobre Enviar Página por Correo Electrónico en Internet Explorer.

lunes, julio 19, 2004

Controlando Foobar con accesos directos

Un pequeño apunte que puede resultar interesante para los que utilicen Foobar como reproductor de música es que la reproducción se puede controlar añadiendo un parámetro al llamar al ejecutable. Por ejemplo:

  • g:\foobar2000\foobar.exe /play Reproducir
  • g:\foobar2000\foobar.exe /stop Parar
  • g:\foobar2000\foobar.exe /pause Pausar
  • g:\foobar2000\foobar.exe /next Siguiente Canción
  • g:\foobar2000\foobar.exe /prev Canción Anterior
  • g:\foobar2000\foobar.exe /rand Modo de reproducción aleatorio

Puede ser util para por ejemplo añadir estos accesos directos a la barra de inicio rápido y poder controlar el reproductor desde ahí.

Album Art Tool

Los vagos tenemos la suerte de que exista gente como el creador de Str8dog, que nos ofrece una herramienta para descargar las imágenes de los albunes mp3 de nuestro PC desde Amazon llamada AlbumArtTool.

La aplicación es GPL, pero solo esta disponible para Windows y da buenos resultados siempre y cuando los mp3s tengan sus correspondientes ID tags rellenados para identificar los albums. En mi caso en concreto identificó correctamente un 90% de mi música :)

Es hora de buscar una alternativa a IE

Me he perdido unas cuantas cosas durante las vacaciones, entre ellas un artículo con un par de pequeñas reviews de Mozilla Firefox y Opera de PC Magazine llamada Time to Find an IE Alternative? en la que se otorga a Firefox 4 puntos sobre 5 (lo cual es muy alentador teniendo en cuenta que estamos en una versión 0.9) frente a los 3.5 puntos de Opera.

Bookmarklets

El primer post después de las vacaciones es para hablar de un par de bookmarklets interesantes, es decir, pequeños fragmentos de código javascript que pueden ser añadido al navegador en forma de marcador (favoritos en terminología IE).

El primer bookmarklet, de Jeff Mesnil nos permite dividir una página HTML en dos marcos, horizontal o verticalmente; el segundo, de Jesse Ruderman añade una barra de desplazamiento y un botón de pausa a las animaciones Flash y funciona en Mozilla e IE.

De vuelta al trabajo

Vengo descansado y morenito después de la semanita de vacaciones :) Mucha playa, mucho sol, muy buena comida, algo de cultura y turismo. En resumen unas buenas vacaciones :)

domingo, julio 11, 2004

Cerrado por vacaciones

Lo dicho, hasta el domingo de la semana que viene me toca descansar que me lo merecía. Me voy a Granada y para poner los dientes largos a todo el que pueda, una cita de mi niña sobre su ciudad (a ver, que va a decir ella de su ciudad ):

una ciudad llena de encantos y lugares mágicos, con un ambiente de tapeo único en España y el mejor lugar para hacer millones de cosas en tus vacaciones: si quieres playa, la tienes a una hora, que te apetece montaña, no problemo, en media horita estás en la cumbre de la península, que quieres hacer de turista, la ciudad está plagada de monumentos, que lo único que te importa es disfrutar, pues no tienes más que salir por la ciudad.

sábado, julio 10, 2004

Reemplazando la Línea de Comandos de Windows

Aunque la gente que no utilice Linux no lo crea, las aplicaciones para Linux suelen ser mas vistosas (y mas potentes, además de muchas veces de código abierto o gratuitas) que sus contrapartidas en Windows. Ese es el caso de la línea de comandos; la consola de Windows es cuanto menos pobre, tanto en aspecto como en potencia, pero podemos reemplazarla con otras aplicaciones similares.

Un primer ejemplo es eConsole, que se parece bastante al Eterm de Linux. Si usamos eConsole en lugar del aburrido cmd lo primero que veremos es que eConsole soporta los estilos visuales de Windows XP (la barra y los botones de cmd son siempre los mismos, no se adaptan al estilo que estes utilizando). eConsole nos permite además asignarle una imagen de fondo, hacer la ventana transparente, pegar la ventana al escritorio o auto esconder la ventana.

Otras opciones similares son Console, basada en eConsole, algo mas rápido y con soporte de transparencias alfa en Windows 2000 y Console2 que se basa a su vez en Console y tiene soporte de sombras para las letras y de antialiasing.

Pero las opciones que hemos visto hasta ahora solamente mejoran algo el aspecto del cmd de Windows, sin añadirle ninguna otra opción de utilidad. En ese sentido la referencia es JP Software con 4DOS, Take Command y 4NT o la combinación de la shell que utilicemos, ya sea cmd como cualquiera de las nombradas, con colecciones de comandos unix compilados para Windows como son las GNU utilities for Win32.

Siguiendo esta última aproximación, además, la opción para los fanáticos de Linux es utilizar cygwin con el que podremos hacer cosas como correr bash en Windows.