Noticias Weblogs Foros Wiki Código

Meta-Info

¿Que es?

Planeta Código es un agregador de weblogs sobre programación y desarrollo en castellano. Si eres lector te permite seguirlos de modo cómodo en esta misma página o mediante el fichero de subscripción.

rss subscripción

Sponsors

Puedes utilizar las siguientes imagenes para enlazar PlanetaCodigo:
planetacodigo

planetacodigo

Si tienes un weblog de programación y quieres ser añadido aquí, envíame un email solicitándolo.

Idea: Juanjo Navarro

Diseño: Albin

Escuela De Codigo

CoffeeScript, El primer paso

Enero 30th, 2012 - [Enlace local]

En esta era de la web2.0, en la que toda actividad y aplicación es llevada a la internet, la nube, un lenguaje antes subestimado, se convirtió para sorpresa de algunos, alegría de otros y desdicha de pocos en un fuerte aliado para los desarrolladores, no hablo de HTML ni CSS sino del tercer componente del triunvirato de la web actual: Javascript.

Javascript un lenguaje interpretado, del lado de cliente, que en sus inicios se usaba en las paginas web para crear efectos de copos de nieve y tonterías de ese tipo. Ahora es el lenguaje sin el cual Gmail no fuera posible, facebook solo seria una galería de fotos aburrida y un twitt seguiria siendo el sonido que algunos creen que hacen los pájaros. Javascript se convirtió en un lenguaje muy importante. Pero, sigue manteniendo muchas cosas que aun no se ajustan al nuevo capricho de los desarrolladores actuales:Syntactic Sugar.

Syntactic Sugar se ha hecho muy popular sobre todo (según como lo veo) gracias a Ruby, y es que eso de escribir código sin puntos y coma, corchetes, llaves y paréntesis innecesarios es una buena idea y hay muchos que piensan que esas ideas es bueno llevarlas a otros lados.

y así fue como nació CoffeeScript,un lenguaje de programación que se escribe bonito y genera Javascript de toda la vida.

Instalación

Para instalar Coffeescript, necesitamos primeramente instalar Node.js y npm, una vez ya lo hallas hecho solo ejecuta en tu terminal favorita

npm install -g coffee-script

(El parametro -g es para indicar que es una instalación global que estara disponible para todos los usuarios de tu sistema operativo)

Hola Mundo

Hagamos una prueba para identificar que todo esta instalado correctamente, y de paso explicar como compilar javascript, abre un editor de texto de tu eleccion y escribe.

square = (x) -> x * x

Guarda tu archivo como hola.coffee (Si, .coffee es la extensión de los script CoffeeScript)

y luego ejecuta

coffee -c 'hola.coffee'

Inmediatamente veras un archivo javascript que se genero con el siguiente código

square = function(x) { return x * x; };

y ya tienes un archivo .js de toda la vida que puedes usar sin problema en tus aplicaciones web.

Ahora bien el comando -c es el que nos sirve para compilar nuestros archivos .coffee y convertirlos en Javascript, claro que se vuelve tedioso estar corriendo ese comando por cada vez que escribo y/o modifico en mi archivo, asi que para evitarnos la fatiga de esa tarea, ejecuta

coffee --watch --compile hola.coffee

Y ahora cada vez que modifiques tu programa Coffeescript, este auto-mágicamente generara el compilado.

Un ejemplo practico

Tengo un archivo javascript de un viejo bookmarklet que hice hace un tiempo, como en ese momento no conocia CoffeeScript pues lo hice a Javascript duro y maduro. ¿Porque no lo migramos a algo mas elegante y comentamos las partes mas interesantes? Nada como un ejemplo practico para aprender mejor las cosas, o alguien aprendio a andar en bicicleta por internet?? ;)

(Que hace el bookmarklet?…elimina el teclado virtual de la siguiente pagina y permite al usuario utilizar nuevamente el teclado convencional, un banco de mi país penso que era buena idea, a mi me pareció incomodo, así que lo quite :D )

El código original lo puedes encontrar aquí

var ifr = false;

var formName = 'loginForm';
#Comentarios

ifr = off

formName = 'loginForm'

Variables

El script empieza definiendo unas cuantas variables,en CoffeeScript para definir variables no es necesario usar la palabra reservada var y en terminos generales los punto y coma no son requeridos.

Comentarios

Los comentarios no son compilados a javascript y se escriben anteponiendo #

Booleanos

Ademas cuando tenemos alguna variable de tipo booleana, podemos utilizar alguno de los alias que el lenguaje nos ofrece para este caso podemos sustituir el false con off o no, para true se utilizan yes o on.

var $ = function(idname) {
var doc = ifr ? window.frames.working.document : document;
return doc.getElementById(idname) ||
doc.getElementsByName(idname)[0] || '';
};

$ = (idname) ->
doc = if ifr then window.frames.working.document else document
doc.getElementById(idname) or
doc.getElementsByName(idname)[0] or ''

Funciones

Las funciones se definen siguiendo la estructura nombre = (parametros entre parentesis) -> [cuerpo de la funcion] sino existen parametros se omiten los parentesis, la palabra reservada return se omite, al igual que en Ruby, la ultima sentencia que se ejecuta es el valor que la funcion devuelve. Los parametros pueden tener valores por defecto parametro='valor'.

Sentencias condicionales

Para definir un if corto (condicion?true:false) se utiliza un lenguaje mas natural if condicion then true else false. Es de notar que las llaves y paréntesis tampoco son necesarios.

Operadores Lógicos

Los operadores logicos tambien tienen alias, para el caso de || se puede sustituir con or

for (var i=0; i<usuario.length; i++){
var caracter = usuario[i];
k = k + $(caracter).value;
}

var letras = new Array();

for (var i=32; i<170; i++){

letras[i] = String.fromCharCode(i);

}

for caracter in usuario
k = k + $(caracter).value

letras = (String.fromCharCode(i) for i in [32..169])

 

 

 

Sentencias repetitivas

El clasico de toda la vida for se abrevia, ya no necesitamos conocer la longitud del arreglo a iterar, ni definir alguna variable auxiliar,CoffeeScript se encarga de todo eso.

Arreglos

Para crear un arreglo basta utilizar nombre = [] aunque para el ejemplo que tenemos creamos un arreglo a partir de una sentencia for y un rango.

Rangos

En el código del bookmarklet necesitaba obtener todas las letras del alfabeto, para lograr eso lo hice con la funcion fromCharCode, que me pide un numero para devolverme el carácter que le corresponde, la opcion en Javascript es crear un loop (for) que inicie en 32 y termine en 169, en CoffeeScript podemos hacer eso haciendo uso de los rangos [inicio..final] . Los rangos son utilizados en las sentencias repetitivas y en la definición de arreglos. Es de notar que si existen dos puntos consecutivos entre los valores de inicio y final significa que el valor inicial es incluido dentro del rango, si vemos tres puntos consecutivos (…) significa que el extremo final del rango es excluido.

El resultado final

Y finalmente!! mi Javascript bookmarklet migrado a CoffeeScript

#declaracion de variables
ifr = no;
formName = 'loginForm';
#funciones
iisIframe = ->
window.location.href=='https://www.pcbac.com/PotalaPersonal/home.do';
window.iisIframe = iisIframe

#Ojo con los espacios es importante!!!
$ = (idname) ->
doc = if ifr then window.frames.working.document else document #if else
doc.getElementById(idname) or
doc.getElementsByName(idname)[0] or ''

window.$ = $;

createHTMLElement = (id,type) ->
_parent = $(id).parentNode
_parent.innerHTML = ''
_input = document.createElement 'input'
_input.setAttribute 'type', type
_input.setAttribute 'id', id
_input.setAttribute 'name', id
_input.setAttribute 'size', '32'
_input.setAttribute 'autocomplete', 'off' #los parentesis no son necesarios
_input.setAttribute 'class', 'notfocussed'
_input.setAttribute 'onblur', if ifr then 'parent.copyText(this);' else 'copyText(this);'
_parent.appendChild _input
return #coloco esto para que mi funcion no retorne nada

window.createHTMLElement = createHTMLElement

copyText = (caja) ->
usuario = caja.value
k = ''
for caracter in usuario
k = k + $(caracter).value

if caja.id=='usernameA' or caja.id=='claveActual' then $('Field1ValueHidden').value = k
if caja.id=='passwordA' or caja.id=='nuevaClave' then $('Field2ValueHidden').value = k
if caja.id=='confirmacionNuevaClave' then $('Field3ValueHidden').value = k

return

window.copyText = copyText;

ifr=iisIframe()
if ifr then formName='cambioClaveForm'
firstRowSplit = $(formName).charFirstRowhidden.value
secondRowSplit = $(formName).charSecondRowhidden.value
thirdRowSplit = $(formName).charThirdRowhidden.value
firstRowSplitMi = $(formName).charFirstRowhiddenHMi.value
secondRowSplitMi = $(formName).charSecondRowhiddenHMi.value
thirdRowSplitMi = $(formName).charThirdRowhiddenHMi.value
firstRowSplitMa = $(formName).charFirstRowhiddenHMa.value
secondRowSplitMa = $(formName).charSecondRowhiddenHMa.value
thirdRowSplitMa = $(formName).charThirdRowhiddenHMa.value

firstRow = firstRowSplit.split '|'
firstRowMi = firstRowSplitMi.split '|'
firstRowMa = firstRowSplitMa.split '|'
secondRow = secondRowSplit.split '|'
secondRowMi = secondRowSplitMi.split '|'
secondRowMa = secondRowSplitMa.split '|'
thirdRow = thirdRowSplit.split '|'
thirdRowMi = thirdRowSplitMi.split '|'
thirdRowMa = thirdRowSplitMa.split '|'
todo = []
for i in [firstRow.length - 1..0] by -1 #empezar en -1
todo[firstRow[i].toLowerCase()] = firstRowMi[i];todo[firstRow[i]] = firstRowMa[i];
for i in [secondRow.length - 1..0] by -1
todo[secondRow[i].toLowerCase()] = secondRowMi[i];todo[secondRow[i]] = secondRowMa[i];
for i in [thirdRow.length - 1..0] by -1
todo[thirdRow[i].toLowerCase()] = thirdRowMi[i];todo[thirdRow[i]] = thirdRowMa[i];

for m in [0..2]
todo[$(formName).number1[m].value] = $(formName).number1[m].alt;
todo[$(formName).number2[m].value] = $(formName).number2[m].alt;
todo[$(formName).number3[m].value] = $(formName).number3[m].alt;

todo[$(formName).number4.value] = $(formName).number4.alt;

for m in [0..9]
todo[$(formName).button4[m].value] = $(formName).button4[m].alt;

for m in [0..10]
todo[$(formName).button5[m].value] = $(formName).button5[m].alt;
todo[$(formName).button10[m].value] = $(formName).button10[m].alt;

letras = (String.fromCharCode(i) for i in [32..169])

for letra in letras
input = document.createElement 'input'
input.setAttribute 'type', 'hidden'
input.setAttribute 'id', letra
input.setAttribute 'value', todo[letra]
$(formName).appendChild input

if !ifr
createHTMLElement('usernameA','text')
createHTMLElement('passwordA','password')
else
createHTMLElement('claveActual','password')
createHTMLElement('nuevaClave','password')
createHTMLElement('confirmacionNuevaClave','password')

$(if ifr then formName else 'forma1').getElementsByTagName("table")[0].getElementsByTagName("tr")

[if ifr then 14 else 8].style.display = 'none'

 

CoffeeScript es mucho mas

Lo que utilice de CoffeeScript para migrar mi bookmarklet no es ni la décima parte de todo lo que este lenguaje nos ofrece, hay mas temas que tratar pero, no caben en un articulo introductorio, espero haber logrado inculcar un poco de curiosidad para que sigas adelante en el estudio de CoffeeScript. Si ese es tu caso, dejo a tu disposición documentación para dar el siguiente paso

Un curso de CoffeeScript en EscueladeCodigo, completamente gratis, ¿te parece buena idea?

» Leer más, comentarios, etc...

Información legal y técnica