<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
>

<channel>
	<title>Planeta Código</title>
	<link>http://www.planetacodigo.com</link>
	<description>Planeta Código</description>
	<pubDate>Sun, 05 Feb 2012 00:14:29 +0000</pubDate>
	<language>es</language>

		<item>
		<title>Viricmind Labs: Mejorar eficiencia en peticiones AJAX</title>
		<link>http://labs.viricmind.org/2012/02/05/mejorar-eficiencia-en-peticiones-ajax/?utm_source=rss&utm_medium=rss&utm_campaign=mejorar-eficiencia-en-peticiones-ajax</link>
		<pubDate>Sun, 05 Feb 2012 00:02:33 +0000</pubDate>
		<dc:creator>castarco</dc:creator>
		
	<category>Programación</category>
	<category>JavaScript</category>
	<category>PHP</category>
	<category>Desarrollo Web</category>
	<category>tutorial</category>
	<category>Html</category>
	<category>json</category>
	<category>PHP</category>
	<category>PHP</category>
	<category>PHP</category>
	<category>PHP</category>
	<category>PHP</category>
		<guid>http://labs.viricmind.org/2012/02/05/mejorar-eficiencia-en-peticiones-ajax/?utm_source=rss&utm_medium=rss&utm_campaign=mejorar-eficiencia-en-peticiones-ajax</guid>
		<description><![CDATA[La mayoría de desarrolladores de aplicaciones web desean que éstas sean usadas por miles de personas (y si es a la vez, mejor). Cuando se llega a un determinado número de usuarios, es difícil que la aplicación aguante esa carga si no se han tomado ciertas decisiones. La más simple (y probablemente más cara) pasa [...]]]></description>
			<content:encoded><![CDATA[<p ><a href="http://labs.viricmind.org/wp-content/uploads/2012/02/json160.png"><img class="alignleft size-full wp-image-1172" title="JSON logo" src="http://labs.viricmind.org/wp-content/uploads/2012/02/json160.png" alt="JSON logo" width="160" height="160" /></a>La mayoría de desarrolladores de aplicaciones web desean que éstas sean usadas por miles de personas (y si es a la vez, mejor). Cuando se llega a un determinado número de usuarios, es difícil que la aplicación aguante esa carga si no se han tomado ciertas decisiones. La más simple (y probablemente más cara) pasa por añadir más prestaciones a los servidores con los que trabaja nuestra app, pero evidentemente podemos encontrar soluciones ligeramente mejores.</p>
<p >Hoy en día es extraño encontrar una aplicación web que no haga uso de <a href="http://es.wikipedia.org/wiki/AJAX">AJAX</a>, unas lo hacen de manera inteligente y otras no tanto. Vamos a ver qué podemos hacer para reducir un poco(en caso de no haberlo hecho ya) la carga que deben soportar nuestros servidores.</p>
<p >El consejo básico es simple: es preferible que el contenido dinámico sea generado en el lado del cliente con <a href="http://es.wikipedia.org/wiki/JavaScript">Javascript</a> a que el trabajo lo hagan nuestras máquinas. Es claro que no siempre se podrá hacer eso, pero por lo general sí, como ejemplo tenemos datos que se actualizan periódicamente o que se estructuran de forma tabular o en listados.</p>
<p >La justificación del consejo radica en 2 puntos, en primer lugar podemos reducir el tiempo de <a href="http://es.wikipedia.org/wiki/Unidad_central_de_procesamiento">CPU</a> en el servidor consumido por petición, en segundo lugar podemos reducir el ancho de banda usado si enviamos datos como <a href="http://es.wikipedia.org/wiki/JSON">JSON</a> en vez de contenido <a href="http://es.wikipedia.org/wiki/HTML">HTML</a> pregenerado. Así dicho suena creíble, pero tenemos que comprobarlo (me fijaré en el caso concreto de <a href="http://es.wikipedia.org/wiki/PHP">PHP</a>).</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code"><pre class="php" ><span ><?php</span>
&nbsp;
<span >// Codigo que sirve petición con JSON</span>
<span >$link</span> <span >=</span> <span >mysql_connect</span><span >&#40;</span><span >'xxx'</span><span >,</span> <span >'xxx'</span><span >,</span> <span >'xxx'</span><span >&#41;</span><span >;</span>
&nbsp;
<span >mysql_select_db</span><span >&#40;</span><span >'xxx'</span><span >&#41;</span><span >;</span>
&nbsp;
<span >$dbresult</span> <span >=</span> <span >mysql_query</span><span >&#40;</span><span >'SELECT nick, passwd, name FROM json'</span><span >&#41;</span><span >;</span>
&nbsp;
<span >$outresult</span> <span >=</span> <span >array</span><span >&#40;</span><span >&#41;</span><span >;</span>
&nbsp;
<span >while</span> <span >&#40;</span><span >$outresult</span><span >&#91;</span><span >&#93;</span> <span >=</span> <span >mysql_fetch_row</span><span >&#40;</span><span >$dbresult</span><span >&#41;</span><span >&#41;</span><span >;</span>
<span >array_pop</span><span >&#40;</span><span >$outresult</span><span >&#41;</span><span >;</span>
&nbsp;
<span >echo</span> <span >json_encode</span><span >&#40;</span><span >$outresult</span><span >&#41;</span><span >;</span>
&nbsp;
<span >mysql_close</span><span >&#40;</span><span >$link</span><span >&#41;</span><span >;</span>
&nbsp;
<span >?></span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="php" ><span ><?php</span>
&nbsp;
<span >// Codigo que sirve la petición con HTML</span>
&nbsp;
<span >$link</span> <span >=</span> <span >mysql_connect</span><span >&#40;</span><span >'xxx'</span><span >,</span> <span >'xxx'</span><span >,</span> <span >'xxx'</span><span >&#41;</span><span >;</span>
&nbsp;
<span >mysql_select_db</span><span >&#40;</span><span >'xxx'</span><span >&#41;</span><span >;</span>
&nbsp;
<span >$dbresult</span> <span >=</span> <span >mysql_query</span><span >&#40;</span><span >'SELECT nick, passwd, name FROM json'</span><span >&#41;</span><span >;</span>
&nbsp;
<span >while</span> <span >&#40;</span><span >$row</span> <span >=</span> <span >mysql_fetch_row</span><span >&#40;</span><span >$dbresult</span><span >&#41;</span><span >&#41;</span> <span >&#123;</span>
    <span >echo</span> <span >'<tr><td>'</span><span >,</span><span >$row</span><span >&#91;</span><span >0</span><span >&#93;</span><span >,</span><span >'</td><td>'</span><span >,</span><span >$row</span><span >&#91;</span><span >1</span><span >&#93;</span><span >,</span><span >'</td><td>'</span><span >,</span><span >$row</span><span >&#91;</span><span >2</span><span >&#93;</span><span >,</span><span >'</td></tr>'</span><span >;</span>
<span >&#125;</span>
&nbsp;
<span >mysql_close</span><span >&#40;</span><span >$link</span><span >&#41;</span><span >;</span>
&nbsp;
<span >?></span></pre></td></tr></table></div>

<p >Antes de hablar sobre como se procesa la petición en el lado del cliente haré algunas observaciones. Aunque en este código no está, añadí código para medir cuantos milisegundos tardaba cada script en ejecutarse. Para aumentar la fiabilidad de las pruebas conté solo el tiempo que se tarda en procesar el resultado de la consulta a la base de datos y enviarla. Así pues excluyo el acceso a la base de datos y el cierre de la conexión de las medidas efectuadas, que son las siguientes (había 200 registros en la base de datos):</p>
<ul>
<li>Petición servida en JSON (10 muestras):</li>
<ul>
<li>Número de bytes enviados: 18830</li>
<li>Pico de memoria consumida: 305128 bytes ~ 297.976 Kb</li>
<li>Tiempo mínimo: 0.62799 ms</li>
<li>Tiempo máximo: 1.2610 ms</li>
<li>Tiempo medio: 0.9064 ms</li>
<li>Desviación típica: 0.1436 ms</li>
</ul>
<li>Petición servida en HTML (10 muestras):</li>
<ul>
<li>Número de bytes enviados: 23854</li>
<li>Pico de memoria consumida: 100008 bytes ~ 97.664 Kb</li>
<li>Tiempo mínimo: 0.7529 ms</li>
<li>Tiempo máximo: 2.4579 ms</li>
<li>Tiempo medio: 1.2909 ms</li>
<li>Desviación típica: 0.4956 ms</li>
</ul>
</ul>
<p >Lo más destacable de estas medidas es el número de bytes enviados, con JSON podemos ahorrar (como mínimo) un 21.06% de ancho de banda. Digo como mínimo porque en este ejemplo el código HTML generado es más bien austero, ya que no incorpora clases <a href="http://es.wikipedia.org/wiki/Hojas_de_estilo_en_cascada">CSS</a> ni identificadores para facilitar el manejo del <a href="http://es.wikipedia.org/wiki/Document_Object_Model">DOM</a>.</p>
<p >El segundo dato nos muestra la cantidad máxima de memoria consumida durante la petición procesada. Como era esperable, la primera versión del código consume más memoria debido al array que va construyendo y a la cadena JSON que ensambla finalmente a partir de la lista generada. En este punto hay que tener en cuenta que, si somos listos, esto no tiene por qué suponer un gran problema ya que ese mismo array podríamos (y de hecho es recomendable) guardarlo usando (por ejemplo) <a href="http://es.wikipedia.org/wiki/Memcached">Memcached</a> de forma que ahorramos posteriores consultas a la base de datos.</p>
<p >Respecto a los otros datos tengo que decir que no son significativos en lo tocante al asunto JSON vs HTML, pues la comparativa no es del todo justa. Sin embargo, lo que sí podemos ver es qué supone usar repetidas veces la primitiva <em>echo</em> frente a un solo uso. Por un lado aumentan los tiempos de ejecución, y por otro aumenta la dispersión de las medidas (ver desviación típica), lo que puede tocar un poco las narices cuando queremos hacer cálculos de cara a escalar nuestra infraestructura.</p>
<p >Otra versión del código que genera HTML es la siguiente:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code"><pre class="php" ><span ><?php</span>
&nbsp;
<span >$link</span> <span >=</span> <span >mysql_connect</span><span >&#40;</span><span >'xxx'</span><span >,</span> <span >'xxx'</span><span >,</span> <span >'xxx'</span><span >&#41;</span><span >;</span>
&nbsp;
<span >mysql_select_db</span><span >&#40;</span><span >'xxx'</span><span >&#41;</span><span >;</span>
&nbsp;
<span >$dbresult</span> <span >=</span> <span >mysql_query</span><span >&#40;</span><span >'SELECT nick, passwd, name FROM json'</span><span >&#41;</span><span >;</span>
&nbsp;
<span >$outresult</span> <span >=</span> <span >''</span><span >;</span>
&nbsp;
<span >while</span> <span >&#40;</span><span >$row</span> <span >=</span> <span >mysql_fetch_row</span><span >&#40;</span><span >$dbresult</span><span >&#41;</span><span >&#41;</span> <span >&#123;</span>
    <span >$outresult</span> <span >.=</span> <span >'<tr><td>'</span><span >.</span><span >$row</span><span >&#91;</span><span >0</span><span >&#93;</span><span >.</span><span >'</td><td>'</span><span >.</span><span >$row</span><span >&#91;</span><span >1</span><span >&#93;</span><span >.</span><span >'</td><td>'</span><span >.</span><span >$row</span><span >&#91;</span><span >2</span><span >&#93;</span><span >.</span><span >'</td></tr>'</span><span >;</span>
<span >&#125;</span>
&nbsp;
<span >echo</span> <span >$outresult</span><span >;</span>
&nbsp;
<span >mysql_close</span><span >&#40;</span><span >$link</span><span >&#41;</span><span >;</span>
&nbsp;
<span >?></span></pre></td></tr></table></div>

<p >Los datos que arroja esta versión son los siguientes:</p>
<ul>
<li>Petición servida en HTML (2ª versión, 10 muestras):</li>
<ul>
<li>Número de bytes enviados: 23854</li>
<li>Pico de memoria consumida: 126432 bytes ~ 123.469 Kb</li>
<li>Tiempo mínimo: 0.3531 ms</li>
<li>Tiempo máximo: 0.8111 ms</li>
<li>Tiempo medio:  0.5435 ms</li>
<li>Desviación típica: 0.1577 ms</li>
</ul>
</ul>
<p >Podemos extraer algunas conclusiones más de esta tercera lista de cifras. En primer lugar se nos podría ocurrir adoptar el mismo enfoque para la generación de JSON, es decir, olvidarnos de construir un array y pasar a construir un string directamente (de hecho obtendríamos mejores resultados, pues la cadena JSON es más corta que la cadena HTML). Si no vamos a usar más esos datos en un lapso de tiempo breve parece lo más acertado, pero si tenemos planeado acceder a ellos otra vez puede que sí nos convenga construir la lista como en el primer ejemplo de código.</p>
<p >Un detalle interesante es que teniendo un array probablemente sea más rápido generar un texto JSON con la función <a href="http://es2.php.net/manual/es/function.json-encode.php">json_encode</a> que concatenando strings en un bucle. El problema que tenemos (en este caso) es que el driver nativo de <a href="http://es.wikipedia.org/wiki/MySQL">MySQL</a> para PHP no permite obtener una lista con todas las filas directamente, y consecuentemente nos vemos forzados a construirla nosotros (que es menos eficiente que usar un método nativo de PHP programado en <a href="http://es.wikipedia.org/wiki/C_(lenguaje_de_programacin)">C</a>, y de ahí que el tercer ejemplo rinda mejor que el segundo).</p>
<p >Tengo que admitir que no conozco por qué no hay un método nativo de PHP para obtener en forma de array todos los resultados de una consulta a una base de datos MySQL, pero creo que, en caso de no haber razones de peso... puede ser una buena jugada implementar en C una <a href="http://es2.php.net/manual/es/internals2.php">extensión del lenguaje</a> que haga precisamente eso para ahorrar un valioso tiempo de ejecución.</p>
<p >En el lado del cliente las diferencias no han sido estadísticamente significativas para mi ejemplo, aunque es de esperar que los tiempos de descarga sean menores con JSON, mientras que los de proceso sean menores con HTML. El tiempo total dependerá de la potencia de cómputo del cliente y del ancho de banda de la conexión, por lo que algunos usuarios saldrán beneficiados mientras que otros puede que tarden algunos milisegundos más en obtener la página web completamente renderizada.</p>
<p >Sin más rodeos, resumen rápido: JSON permite reducir el ancho de banda consumido en más de un 21%, hacer un solo <em>echo</em> reduce el tiempo de ejecución (la reducción puede sobrepasar fácilmente el 50%, en el caso del ejemplo es un 57.89%) y la dispersión estadística de esos mismos tiempos (lo que nos puede ayudar a realizar mejores cálculos para escalar la plataforma o puede servir para que los balanceadores de carga tengan datos más fiables con los que trabajar).</p>
<p >Como apunte final solo quiero destacar que es importante realizar experimentos y comprobar los hechos por uno mismo, pues la tecnología evoluciona constantemente y es probable que ciertas afirmaciones no se puedan sostener en el tiempo. Además me he dejado algunas técnicas en el tintero, como usar los métodos <a href="http://es2.php.net/manual/es/function.ob-start.php">ob_start</a> y <a href="http://es2.php.net/manual/es/function.ob-end-clean.php">ob_end_clean</a>, que nos permiten aprovechar el buffer de escritura para evitar la necesidad de concatenaciones. Espero que viendo la extensión del artículo comprendáis que no lo haya comentado en profundidad. Espero que os haya sido útil <img src='http://labs.viricmind.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
]]></content:encoded>
		</item>
		<item>
		<title>El blog de pico.dev: Recarga de clases (class reloading) en Apache Tapestry</title>
		<link>http://elblogdepicodev.blogspot.com/2012/02/recarga-de-clases-class-reloading-en.html</link>
		<pubDate>Sat, 04 Feb 2012 02:18:00 +0000</pubDate>
		<dc:creator>__OVERFLOW__</dc:creator>
		
	<category>Programación</category>
	<category>Java</category>
	<category>software libre</category>
	<category>JAVA</category>
	<category>Software libre</category>
	<category>JAVA</category>
	<category>Software libre</category>
	<category>JAVA</category>
	<category>planeta linux</category>
	<category>planeta código</category>
	<category>tapestry</category>
		<guid>http://elblogdepicodev.blogspot.com/2012/02/recarga-de-clases-class-reloading-en.html</guid>
		<description><![CDATA[En el mundo Java de desarrollo de aplicaciones web hace no tanto tiempo un cambio en una clase implicaba reiniciar el servidor para ver los cambios. Dado que desarrollando una aplicación los cambios son pequeños, incrementales y numerosos esto implic...]]></description>
			<content:encoded><![CDATA[<div ><img border="0" height="132" src="http://4.bp.blogspot.com/-OGvCbjBk0zU/TOq7Y6w6wfI/AAAAAAAAAiU/Pfuzt5kkDBQ/s320/tapestry.png" width="320" alt="Apache Tapestry" title="Apache Tapestry"></img></div>En el mundo Java de desarrollo de aplicaciones web hace no tanto tiempo un cambio en una clase implicaba reiniciar el servidor para ver los cambios. Dado que desarrollando una aplicación los cambios son pequeños, incrementales y numerosos esto implicaba tener que reiniciar constantemente el servidor que dependiendo de la aplicación esto podría llevar no mucho tiempo, desde 10-30, que ya es un tiempo considerable, pero podría llegar a llevar incluso algunos minutos. El tiempo de espera para cada reinicio normalmente es tiempo no productivo que acumulándolo a lo largo del día puede llegar a ser considerable y por ello los frameworks web están evolucionando a no tener que requerir reiniciar el servidor para detectar las modificaciones, esto es, cogiendo los cambios en caliente. Ello nos permite ser más productivos.<br></br><br></br><a href="http://tapestry.apache.org/">Apache Tapestry</a> evlucionó y no se quedó atras. La recarga de clases o «class reloading» es una característica añadida en Tapestry en la versión 5 para las clases de las páginas y componentes al igual que los archivos .tml de las plantillas y los los archivos de catálogos de mensajes. En la versión 5.2 la recarga de clases se extendió a los servicios definidos en los módulos de Tapestry. El proceso de recarga que hace Tapestry cuando se detecta un cambio en una clase no afecta a los datos persistentes ya que estos se guardan aparte, normalmente en la sesión, con lo que el desarrollo nos será muy cómodo.<br></br><br></br>Si nuestra aplicación tiene como paquete base com.blogspot.elblogdepicodev.tapestry Tapestry recargará las clases de los siguientes paquetes cuando detecte algún cambio:<br></br><ul><li>com.blogspot.elblogdepicodev.tapestry.pages</li><li>com.blogspot.elblogdepicodev.tapestry.components</li><li>com.blogspot.elblogdepicodev.tapestry.mixins</li><li>com.blogspot.elblogdepicodev.tapestry.base</li></ul>Sim embargo, el proceso tiene algunas limitaciones. La recarga solo se aplica a clases y archivos que están en el sistema de archivos y no obtenidos desde archivos JAR. Aunque esta limitación no es importante en desarrollo ya que podemos desplegar la aplicación en nuestro servidor de desarrollo de forma expandida.<br></br><br></br>El coger los cambios en caliente es una característica deseable de todo framework actual pero también hay que tener en cuenta el tiempo de inicio del servidor ya que en algún momento tarde o temprano nos tocará hacerlo, si queremos ser ágiles en el desarrollo no es recomendable esperar varios minutos a que el servidor termine de iniciarse y en producción es necesario que el tiempo de interrupción sea mínimo.<br></br><br></br>Un Tomcat sin ninguna aplicación tarda en iniciarse unos 4 segundos, con una aplicación Tapestry desplegada de forma expandida con Hibernate, EhCache y Quartz de tamaño medio tarda unos 10 segundos y en servir la primera página unos 15-20 segundos.<br></br><br></br>Referencia:<br></br><a href="http://elblogdepicodev.blogspot.com/2010/05/documentacion-sobre-apache-tapestry.html">Documentación sobre Apache Tapestry</a><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/2347950092468997900-2008221984698722393?l=elblogdepicodev.blogspot.com" alt=""></img></div>]]></content:encoded>
		</item>
		<item>
		<title>Ingenieria de Software / Software Engineering / Project Management / Business Process Management: Transición a Windows 8</title>
		<link>http://ingsoftware.blogspot.com/2012/02/transicion-windows-8.html</link>
		<pubDate>Thu, 02 Feb 2012 14:55:00 +0000</pubDate>
		<dc:creator>JorgeBec</dc:creator>
		
	<category>microsoft</category>
		<guid>http://ingsoftware.blogspot.com/2012/02/transicion-windows-8.html</guid>
		<description><![CDATA[InformationWeek presenta una serie de Features que distinguen a Windows 8, preparemos el cambio    ]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.informationweek.com.mx/analysis/preparese-para-la-transicion-a-windows-8/">InformationWeek presenta una serie de Features</a> que distinguen a Windows 8, preparemos el cambio</p>  <p><a href="http://lh3.ggpht.com/-ow2_S5d4Vk4/Tyqjxe6LYOI/AAAAAAAAANc/XM2eCMXouE0/s1600-h/Windows%2525208%25255B2%25255D.jpg"><img  title="Windows 8" border="0" alt="Windows 8" src="http://lh5.ggpht.com/-hbG0ZehhUvM/TyqjxqRw1XI/AAAAAAAAANk/00dlxZKGb4Q/Windows%2525208_thumb.jpg?imgmax=800" width="244" height="184"></img></a></p>  <div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/9995896-1685607525869521385?l=ingsoftware.blogspot.com" alt=""></img></div>]]></content:encoded>
		</item>
		<item>
		<title>Koalite's blog: Tutorial jQuery Mobile + Knockout (II): Creando las vistas con jQuery Mobile</title>
		<link>http://feedproxy.google.com/~r/KoalitesBlog/~3/Yo557ni1XyA/</link>
		<pubDate>Thu, 02 Feb 2012 04:17:25 +0000</pubDate>
		<dc:creator>Juanma</dc:creator>
		
	<category>JavaScript</category>
	<category>tutorial</category>
	<category>development</category>
	<category>jquerymobile</category>
	<category>knockoutjs</category>
		<guid>http://feedproxy.google.com/~r/KoalitesBlog/~3/Yo557ni1XyA/</guid>
		<description><![CDATA[<script type="text/javascript">
				  (function() {
				    var po = document.createElement("script"); po.type = "text/javascript"; po.async = true;
				    po.src = "https://apis.google.com/js/plusone.js";
				    var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(po, s);
				  })();
				</script>Ahora que ya tenemos una idea de qué hacen jQuery Mobile y Knockout, llega el momento de presentar la aplicación de ejemplo que usaremos durante el tutorial. La aplicación: W.I.Z.A.R&#038;D La aplicación que vamos a implementar se llama WIZARD (Weapon Inventory for Zombie Apocalypse Research &#038; Development) y es una aplicación muy sencilla que nos [...]
<strong>Posts relacionados:</strong><ol>
<li><a href='http://blog.koalite.com/2012/01/tutorial-jquery-mobile-knockout-i-sentando-las-bases/' rel='bookmark' title='Tutorial jQuery Mobile + Knockout (I): Sentando las bases'>Tutorial jQuery Mobile + Knockout (I): Sentando las bases</a></li>
<li><a href='http://blog.koalite.com/2011/11/tutorial-node-js-express-jquery-ii-generando-vistas-con-jade/' rel='bookmark' title='Tutorial node.js + express + jquery (II): Generando vistas con Jade'>Tutorial node.js + express + jquery (II): Generando vistas con Jade</a></li>
<li><a href='http://blog.koalite.com/2011/11/tutorial-node-js-express-jquery-i-creando-la-aplicacion/' rel='bookmark' title='Tutorial node.js + express + jquery (I): Creando la aplicación'>Tutorial node.js + express + jquery (I): Creando la aplicación</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Ahora que ya tenemos una idea de <a href="http://blog.koalite.com/2012/01/tutorial-jquery-mobile-knockout-i-sentando-las-bases/" title="Tutorial jQuery Mobile + Knockout (I): Sentando las bases" >qué hacen jQuery Mobile y Knockout</a>, llega el momento de presentar la aplicación de ejemplo que usaremos durante el tutorial. </p>
<h3>La aplicación: W.I.Z.A.R&#038;D</h3>
<p>La aplicación que vamos a implementar se llama WIZARD (Weapon Inventory for Zombie Apocalypse Research &#038; Development) y es una aplicación muy sencilla que nos ayuda a seleccionar las mejores armas para sobrevivir a un <a href="http://es.wikipedia.org/wiki/Zombi_-_Gu%C3%ADa_de_supervivencia" >apocalipsis zombie</a>. Su interfaz de usuario se compone de tres pantallas:</p>
<div id="attachment_1046" class="wp-caption alignnone" ><img src="http://blog.koalite.com/wp-content/uploads/wizard-mockup.jpg" alt="Weapon Inventory for Zombie Apocalypse Research &amp; Development" title="wizard-mockup" width="650" height="373" class="size-full wp-image-1046" /><p class="wp-caption-text">Pantallas de W.I.Z.A.R&#038;D</p></div>
<p>La primera pantalla muestra una lista con las armas que tenemos seleccionadas para sobrevivir al apocalipsis zombie e incluye el peso total de nuestro inventario. Al pulsar sobre un arma se accederá al a segunda pantalla, donde podremos introducir los datos que hemos recogido de ese arma. </p>
<p>También podremos añadir nuevas armas pulsando sobre el botón <em>Añadir</em>, con lo que se mostrará un cuadro diálogo como el de la tercera pantalla. Por último, podremos eliminar armas pulsando sobre el botón de eliminar que aparece a la derecha de cada arma de la lista.</p>
<p>Queda claro con esto que los ejemplos de aplicaciones siguen sin ser lo mío, pero para jugar un poco con jQuery Mobile y Knockout nos puede servir.</p>
<p>Como vimos en la introducción del tutorial, <strong>para representar cada pantalla</strong> (vista en terminología <abbr title="Model-View-ViewModel">MVVM</abbr>) <strong>jQuery Mobile usa elementos <code>div</code> con el atributo <code>data-role="page"</code></strong>. De momento vamos a centrarnos en cómo implementar cada pantalla con jQuery Mobile, sin emplear Knockout ni enganchar eventos de navegación para conocer mejor algunas características de jQuery Mobile. </p>
<h3>La lista de armas</h3>
<p>El código de la pantalla principal de W.I.Z.A.R&#038;D es el siguiente:</p>
<pre class="brush:html">
<div data-role="page" id="home">
	<div data-role="header">
		<h1>W.I.Z.A.R&#038;D</h1>
		<a href="http://feedproxy.google.com/~r/KoalitesBlog/~3/Yo557ni1XyA/#" data-role="button" data-icon="add" class="ui-btn-right">Añadir</a>
	</div>
	<div data-role="content">
		<ul data-role="listview">
			<li>
				<a href="http://feedproxy.google.com/~r/KoalitesBlog/~3/Yo557ni1XyA/#">Martillo</a>
				<a href="http://feedproxy.google.com/~r/KoalitesBlog/~3/Yo557ni1XyA/#" data-role="button" data-icon="delete" data-theme="d"></a>
			</li>
			<!-- Aquí irían el resto de armas -->
		</ul>
	</div>
	<div data-role="footer" data-position="fixed">
		<h3>Peso Total: 3.45 kgs.</h3>
	</div>
</div>
</pre>
<p>Cosas a tener en cuenta:</p>
<ul>
<li><strong>La página queda contenida en un <code>div</code> con el atributo <code>data-role="page"</code></strong>. El <code>id</code> que asignamos al <code>div</code> es importante porque será lo que nos permita identificar la página y navegar hasta ella.</li>
<li><strong>Cada parte de la página tiene asignado su propio rol</strong>. Así tenemos la cabecera (<code>data-role="header"</code>), el contenido (<code>data-role="content"</code>) y el pie (<code>data-role="footer"</code>).</li>
<li><strong>Para mostrar una lista de elementos existe el rol <code>listview</code></strong>. jQuery Mobile es además lo bastante listo para formatearla para que quede bonita y colocar el icono de eliminar a la derecha.</li>
<li>Usando <a href="http://ejohn.org/blog/html-5-data-attributes/" >atributos <code>data-*</code> de HTML5</a> se pueden controlar más cosas, como la posición, el icono o incluso el <a href="http://jquerymobile.com/test/docs/api/themes.html" >tema</a>.</li>
</ul>
<div id="attachment_1057" class="wp-caption alignright" ><a href="http://blog.koalite.com/wp-content/uploads/wizard-weapon-list.png"><img src="http://blog.koalite.com/wp-content/uploads/wizard-weapon-list-168x300.png" alt="Lista de armas de wizard" title="wizard-weapon-list" width="168" height="300" class="size-medium wp-image-1057" /></a><p class="wp-caption-text">Lista de armas. No está mal para lo fácil que ha sido.</p></div>
<p>Un factor a tener en cuenta es que toda <strong>la personalización que hace jQuery Mobile de los elementos html se realiza sólo al mostrar la página por primera vez</strong>, por lo que si añadimos dinámicamente nuevos elementos habrá que indicar a jQuery Mobile que reaplique la personalización. Veremos ejemplos de esto en la siguiente parte del tutorial.</p>
<p>Una cosa que resulta un poco confusa es que a veces para cambiar el aspecto o la posición de algo hay que usar atributos <code>data-*</code>, como el <code>data-position="fixed"</code> que aparece en el <code>footer</code>, y otras veces se usan clases css, como el <code>ui-btn-right</code> del botón de <em>Añadir</em> del <code>header</code>.</p>
<h3>Modificar un arma</h3>
<p>jQuery Mobile permite mantener las distintas páginas, es decir los distintos <code>div</code>s con el atributo <code>data-role="page"</code>, en varios archivos y cargarlas a través de peticiones AJAX. Sin embargo, en este caso, y para mantener las cosas simples, todas las vamos a colocar en el mismo fichero html. El código correspondiente a la página de edición de un arma es éste:</p>
<pre class="brush:html">
<div data-role="page" id="edit">
	<div data-role="header">
		<a href="http://feedproxy.google.com/~r/KoalitesBlog/~3/Yo557ni1XyA/#" data-rel="back" data-role="button" data-icon="back" data-theme="a">Back</a>
		<h1>Martillo</h1>
	</div>
	<div data-role="content">
		<div data-role="fieldcontain">
			<div>
				<label for="weight">Peso</label>
				<input type="number" id="weight" value="1"/>
			</div>
			<div>
				<label for="ammoType">Munición</label>
				<select id="ammoType">
					<option>Ilimitada</option>
					<option>Escasa</option>
					<option>Abundante</option>
				</select>
			</div>
			<div>
				<label for="closeCombatRating">Efectividad cuerpo a cuerpo</label>
				<div id="closeCombatRating">TODO</div>
			</div>
			<div>
				<label for="rangeRating">Efectividad a distancia</label>
				<div id="rangeRating">TODO</div>
			</div>
		</div>
	</div>
</div>
</pre>
<p>No tiene mucho de especial. De momento con este código no se muestran las estrellitas para calificar el arma, eso lo haremos más adelante con Knockout. </p>
<p>Lo más reseñable es que <strong>para añadir un botón para volver a la página anterior sólo hay que añadir el atributo <code>data-rel="back"</code></strong> al enlace y jQuery Mobile se encargará de todo.</p>
<h3>Añadir un nuevo arma</h3>
<p>Este es un caso un poco especial porque esta vista queremos mostrarla como un diálogo en lugar de como una página normal. Para ello usamos el siguiente código:</p>
<pre class="brush:html">
<div data-role="dialog" id="addNew">
	<div data-role="header">
		<h1>Añadir Arma</h1>
	</div>
	<div data-role="content">
		<label for="newWeaponName">Nombre:</label>
		<input type="text" name="newWeaponName"></input>
		<fieldset class="ui-grid-a">
			<div class="ui-block-a"><a href="http://feedproxy.google.com/~r/KoalitesBlog/~3/Yo557ni1XyA/#" data-rel="back" data-role="button">Cancelar</a></div>
			<div class="ui-block-b"><a href="http://feedproxy.google.com/~r/KoalitesBlog/~3/Yo557ni1XyA/#" data-rel="back" data-role="button" data-theme="b">Aceptar</a></div>
		</fieldset>
	</div>
</div>
</pre>
<p><strong>Para crear el diálogo debemos marcar el <code>div</code> con rol <code>data-role="dialog"</code></strong>. De esta forma jQuery Mobile lo tratará como diálogo y le dará otro aspecto. Se supone que el diálogo debe estar siempre en un fichero html distinto, pero lo cierto es que en este ejemplo está todo en el mismo fichero html y funciona correctamente.</p>
<p>En este caso estamos haciendo uso de clases css de jQuery Mobile para colocar los botones de <em>Cancelar</em> y <em>Aceptar</em> uno al lado del otro en lugar de uno encima de otro. Para ello se usa la siguiente estructura:</p>
<pre class="brush:html">
<fieldset class="ui-grid-a">
	<div class="ui-block-a"><a href="http://feedproxy.google.com/~r/KoalitesBlog/~3/Yo557ni1XyA/#" data-rel="back" data-role="button">Cancelar</a></div>
	<div class="ui-block-b"><a href="http://feedproxy.google.com/~r/KoalitesBlog/~3/Yo557ni1XyA/#" data-rel="back" data-role="button" data-theme="b">Aceptar</a></div>
</fieldset>
</pre>
<p>Al englobar ambos botones en un <code>fieldset</code> con la clase <code>ui-grid-a</code> jQuery Mobile monta un <a href="http://blog.koalite.com/2012/01/diseno-web-sensible-y-grids-css/" title="Diseño Web Sensible y Grids CSS" >grid</a> que nos permite colocarlos en línea.</p>
<p>Para apreciar la diferencia entre usar un <code>data-role="dialog"</code> y un <code>data-role="page"</code>, nada mejor que una captura de pantalla:</p>
<div id="attachment_1063" class="wp-caption aligncenter" ><a href="http://blog.koalite.com/wp-content/uploads/wizard-add-weapon.png"><img src="http://blog.koalite.com/wp-content/uploads/wizard-add-weapon-e1328132349948-300x223.png" alt="Wizard add weapon dialog" title="wizard-add-weapon" width="300" height="223" class="size-medium wp-image-1063" /></a><p class="wp-caption-text">Así son los diálogos. Nada que ver con las páginas.</p></div>
<h3>Por donde seguimos</h3>
<p>Lo que tenemos de momento no son más que unas cuantas páginas estáticas e inconexas entre las que ni siquiera podemos navegar. En la próxima parte del tutorial introduciremos Knockout en la aplicación para tener un <em>ViewModel</em> con el que interactuar y hacer la cosa un poco más interesante.</p>
<p>De todas formas, si quieres ver <strong>el código completo del tutorial lo puedes encontrar ya en su <a href="https://github.com/jmhdez/wizard" >repositorio de github</a></strong>.</p>
<div class="trackable_sharing"><div class="trackable_sharing_text"><b><br/><br/><br/>Compartir enlace:
</b></div><a href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fblog.koalite.com%2F2012%2F02%2Ftutorial-jquery-mobile-knockout-ii-creando-las-vistas-con-jquery-mobile%2F"  title="Facebook"  onclick="that=this;_gaq.push(['_trackEvent','SocialSharing','Facebook','http://blog.koalite.com/2012/02/tutorial-jquery-mobile-knockout-ii-creando-las-vistas-con-jquery-mobile/']); _trackableshare_window = window.open(this.href,'share','menubar=0,resizable=1,width=500,height=350'); _trackableshare_window.focus(); return false;"><img align="absmiddle" src="http://blog.koalite.com/wp-content/plugins/trackable-social-share-icons/buttons/f2//facebook.png" alt="Facebook" width="36" height="36"></a> <a href="http://twitter.com/share?url=http%3A%2F%2Fblog.koalite.com%2F2012%2F02%2Ftutorial-jquery-mobile-knockout-ii-creando-las-vistas-con-jquery-mobile%2F&text=Tutorial+jQuery+Mobile+%2B+Knockout+%28II%29%3A+Creando+las+vistas+con+jQuery+Mobile"  title="Twitter"  onclick="that=this;_gaq.push(['_trackEvent','SocialSharing','Twitter','http://blog.koalite.com/2012/02/tutorial-jquery-mobile-knockout-ii-creando-las-vistas-con-jquery-mobile/']); _trackableshare_window = window.open(this.href,'share','menubar=0,resizable=1,width=500,height=350'); _trackableshare_window.focus(); return false;"><img align="absmiddle" src="http://blog.koalite.com/wp-content/plugins/trackable-social-share-icons/buttons/f2//twitter.png" alt="Twitter" width="36" height="36"></a> <a href="mailto:?subject=Check%20out%20http%3A%2F%2Fblog.koalite.com%2F2012%2F02%2Ftutorial-jquery-mobile-knockout-ii-creando-las-vistas-con-jquery-mobile%2F"  title="Email" onclick="that=this;_gaq.push(['_trackEvent','SocialSharing','Email','http://blog.koalite.com/2012/02/tutorial-jquery-mobile-knockout-ii-creando-las-vistas-con-jquery-mobile/']); "><img align="absmiddle" src="http://blog.koalite.com/wp-content/plugins/trackable-social-share-icons/buttons/f2//email.png" alt="Email" width="36" height="36"></a> <br /><g:plusone annotation="none"></g:plusone></div><p><strong>Posts relacionados:</strong></p><ol>
<li><a href='http://blog.koalite.com/2012/01/tutorial-jquery-mobile-knockout-i-sentando-las-bases/' rel='bookmark' title='Tutorial jQuery Mobile + Knockout (I): Sentando las bases'>Tutorial jQuery Mobile + Knockout (I): Sentando las bases</a></li>
<li><a href='http://blog.koalite.com/2011/11/tutorial-node-js-express-jquery-ii-generando-vistas-con-jade/' rel='bookmark' title='Tutorial node.js + express + jquery (II): Generando vistas con Jade'>Tutorial node.js + express + jquery (II): Generando vistas con Jade</a></li>
<li><a href='http://blog.koalite.com/2011/11/tutorial-node-js-express-jquery-i-creando-la-aplicacion/' rel='bookmark' title='Tutorial node.js + express + jquery (I): Creando la aplicación'>Tutorial node.js + express + jquery (I): Creando la aplicación</a></li>
</ol><img src="http://feeds.feedburner.com/~r/KoalitesBlog/~4/Yo557ni1XyA" height="1" width="1"/>]]></content:encoded>
		</item>
		<item>
		<title>Ingenieria de Software / Software Engineering / Project Management / Business Process Management: KPI Library</title>
		<link>http://ingsoftware.blogspot.com/2012/02/kpi-library.html</link>
		<pubDate>Thu, 02 Feb 2012 00:03:00 +0000</pubDate>
		<dc:creator>JorgeBec</dc:creator>
		
	<category>Business Intelligence</category>
		<guid>http://ingsoftware.blogspot.com/2012/02/kpi-library.html</guid>
		<description><![CDATA[Todo un compendio de KPI´s ordenado por industria y por proceso, sin duda alguna un sitio de referencia para Business Intelligence  http://kpilibrary.com/  ]]></description>
			<content:encoded><![CDATA[<p>Todo un compendio de KPI´s ordenado por industria y por proceso, sin duda alguna un sitio de referencia para Business Intelligence</p>  <p><a title="http://kpilibrary.com/" href="http://kpilibrary.com/">http://kpilibrary.com/</a></p>  <div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/9995896-3245233093527234510?l=ingsoftware.blogspot.com" alt=""></img></div>]]></content:encoded>
		</item>
		<item>
		<title>Variable not found: Validación manual con Data Annotations</title>
		<link>http://feedproxy.google.com/~r/vnf/~3/Wu39XxmnfDk/validacion-manual-con-data-annotations.html</link>
		<pubDate>Wed, 01 Feb 2012 10:47:00 +0000</pubDate>
		<dc:creator>José M. Aguilar</dc:creator>
		
	<category>.NET</category>
	<category>Trucos</category>
	<category>validadores</category>
		<guid>http://feedproxy.google.com/~r/vnf/~3/Wu39XxmnfDk/validacion-manual-con-data-annotations.html</guid>
		<description><![CDATA[ Habitualmente asociamos la validación de entidades basadas en anotaciones de datos, o data annotations, a tecnologías como dynamic data o ASP.NET MVC, y estamos acostumbrados a que la validación se realice de forma automática, pero nada más lejos...]]></description>
			<content:encoded><![CDATA[<img align="right" alt="Microsoft .NET" border="0" height="50" src="http://lh5.ggpht.com/-y33LGS5zgnE/Tv8yaqnLUTI/AAAAAAAABts/TPejSo7Odpo/image%25255B2%25255D.png?imgmax=800"  title="Microsoft .NET" width="199"></img> Habitualmente asociamos la validación de entidades basadas en anotaciones de datos, o <em>data annotations</em>, a tecnologías como <em>dynamic data</em> o ASP.NET MVC, y estamos acostumbrados a que la validación se realice de forma automática, pero nada más lejos de la realidad. <strong>Podemos utilizar <em>data annotations</em> desde cualquier tipo de aplicación .NET</strong> (Webforms, Winforms, WPF, Consola, o cualquier otra en la que tengamos disponible <span >System.ComponentModel.DataAnnotations</span>), puesto que existe la posibilidad de invocar manualmente los procedimientos de validación.<br></br>
<br></br>
En este post vamos a ver <strong>cómo realizar validaciones basadas en anotaciones de forma manual</strong>, lo cual puede tener su utilidad en gran número de escenarios.<br></br>
<a name="more"></a><br></br>
Resumidamente, esta técnica consiste en decorar cada una de las propiedades con una serie de atributos llamados anotaciones (definidos en <code>System.ComponentModel.DataAnnotations</code>)&nbsp; que indican las comprobaciones que se aplicarán a la entidad para determinar su validez. La siguiente porción de código muestra una entidad en la que se están indicando estas restricciones en cada una de sus propiedades:<br></br>
<pre ><span ><span ><span >public</span></span><span >&nbsp;<span >class</span>&nbsp;<span >Friend</span>
{
&nbsp;&nbsp;&nbsp; [<span >Required</span>, <span >StringLength(<span >50</span>)</span>]
&nbsp;&nbsp;&nbsp; <span >public</span>&nbsp;<span >string</span> Name { <span >get</span>; <span >set</span>; }
 
&nbsp;&nbsp;&nbsp; [<span >Range</span>(0, 120)]
&nbsp;&nbsp;&nbsp; <span >public</span>&nbsp;<span >int</span> Age { <span >get</span>; <span >set</span>; }
}</span></span></pre>
En el citado espacio de nombres encontramos <strong>atributos que cubren la mayoría de casos</strong> frecuentes: <code>Required</code> (propiedad obligatoria), <code>RegularExpression</code> (validar contra una expresión regular), <code>StringLength (</code>longitud máxima y mínima de un texto), <code>Range</code> (rangos de valores permitidos), y <code>CustomValidation</code> (validaciones personalizadas). Además, este conjunto de anotaciones puede ser extendido muy fácilmente creando atributos que hereden de <code>ValidationAttribute</code>, disponible también en <code>System.ComponentModel.DataAnnotations</code>.<br></br>
<h3>






Validación manual de objetos</h3>
De lo más sencillo: la clase estática <code>Validator</code>, disponible también en el <em>namespace</em> <code>System.ComponentModel.DataAnnotations</code>, ofrece métodos que permiten realizar las comprobaciones de forma directa sobre objetos o propiedades concretas.<br></br>
<br></br>
En este caso, dado que lo que nos interesa es validar las entidades completas, utilizaremos el método <code>Validator.TryValidateObject()</code>, al que suministraremos:<br></br>
<ul>
<li>el objeto a validar, </li>
<li>un contexto de validación (que debemos crear previamente), </li>
<li>una colección de <code>ValidationResult</code> en la que almacenaremos los errores, </li>
<li>y, por último, si deseamos validar todas las propiedades (indicando <code>true</code>), o por el contrario preferimos parar el proceso en cuanto se detecte el primer error (<code>false</code>). </li>
</ul>
La implementación de la validación podría ser como la que la sigue:<br></br>
<pre ><span ><span >&nbsp;&nbsp;&nbsp; <span >private</span>&nbsp;<span >IEnumerable</span>&lt;<span >ValidationResult</span>&gt; getValidationErrors(<span >object</span> obj)
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >var</span> validationResults = <span >new</span>&nbsp;<span >List</span>&lt;<span >ValidationResult</span>&gt;();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >var</span> context = <span >new</span>&nbsp;<span >ValidationContext</span>(obj, <span >null</span>, <span >null</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >Validator</span>.TryValidateObject(obj, context, validationResults, <span >true</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >return</span> validationResults;
&nbsp;&nbsp;&nbsp; }</span></span></pre>
El método retornará una lista de errores vacía cuando el objeto haya superado las restricciones impuestas, o llena con los objetos <code>ValidationResult</code> que describen los problemas encontrados.<br></br>
<br></br>
Y podríamos utilizarlo desde una aplicación de consola de la siguiente forma:<br></br>
<pre ><span ><span >&nbsp;&nbsp;&nbsp; <span >var</span> friend = <span >new</span>&nbsp;<span >Friend</span> { Age = -1, Name = <span >""</span> };
&nbsp;&nbsp;&nbsp; <span >var</span> errors = getValidationErrors(friend);
&nbsp;&nbsp;&nbsp; <span >foreach</span> (<span >var</span> error <span >in</span> errors)
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >Console</span>.WriteLine(error.ErrorMessage);
&nbsp;&nbsp;&nbsp; }</span></span></pre>
<div >
The Name field is required. <br></br>
<br></br>
The field Age must be between 0 and 120. </div>
Los mensajes de validación que aparecen pueden ser definidos en la misma anotación, por ejemplo así:<br></br>
<pre ><span ><span >&nbsp;&nbsp;&nbsp; [<span >Required</span>(ErrorMessage=<span >"Please, enter the name"</span>)]
&nbsp;&nbsp;&nbsp; <span >public</span>&nbsp;<span >string</span> Name { <span >get</span>; <span >set</span>; }</span></span></pre>
<h3>






¿Y si los metadatos están en otra clase?</h3>
<strong>Hay escenarios en los que no tenemos acceso a la clase</strong> en la que deseamos introducir las anotaciones. Un ejemplo claro lo encontramos cuando nos interesa especificar las restricciones en una clase generada por un proceso automático, como el diseñador de EDM de Entity framework; cualquier cambio realizado sobre el código generado será sobrescrito sin piedad al modificar el modelo.<br></br>
<br></br>
En estos casos, <strong>es una práctica frecuente definir los metadatos en clases “buddy”</strong>, que son copias exactas de la entidad a anotar, pero que serán utilizadas únicamente como contenedores de anotaciones. Las clases buddy se vinculan con la entidad original utilizando el atributo <code><a href="http://msdn.microsoft.com/es-es/library/system.componentmodel.dataannotations.metadatatypeattribute.aspx">MetadataType</a></code> de la siguiente forma:<br></br>
<pre ><span ><span >&nbsp;&nbsp;&nbsp; <span >// This class has been generated by a tool</span>
&nbsp;&nbsp;&nbsp; <span >public</span>&nbsp;<span >partial</span>&nbsp;<span >class</span>&nbsp;<span >Friend</span>
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >public</span>&nbsp;<span >string</span> Name { <span >get</span>; <span >set</span>; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >public</span>&nbsp;<span >int</span> Age { <span >get</span>; <span >set</span>; }
&nbsp;&nbsp;&nbsp; }
 
&nbsp;&nbsp;&nbsp; <span >// Let's associate the buddy class FriendMetadata</span>
&nbsp;&nbsp;&nbsp; <span >[<span >MetadataType</span>(<span >typeof</span>(<span >FriendMetadata</span>))]</span>
&nbsp;&nbsp;&nbsp; <span >public</span>&nbsp;<span >partial</span>&nbsp;<span >class</span>&nbsp;<span >Friend</span>
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; }
 
&nbsp;&nbsp;&nbsp; <span >// Buddy class</span>
&nbsp;&nbsp;&nbsp; <span >public</span>&nbsp;<span >class</span>&nbsp;<span >FriendMetadata</span>
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [<span >Required</span>]
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >public</span>&nbsp;<span >string</span> Name { <span >get</span>; <span >set</span>; }
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [<span >Range</span>(0, 120)]
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >public</span>&nbsp;<span >int</span> Age { <span >get</span>; <span >set</span>; }
&nbsp;&nbsp;&nbsp; }</span></span></pre>
Observad que para poder utilizar esta técnica es necesario que la entidad a la que queremos añadir anotaciones sea creada como parcial. En caso contrario no podríamos indicarle con <code>MetadataType</code> dónde se encuentran definidos sus atributos de validación.<br></br>
<br></br>
Pues bien, resulta que algunos marcos de trabajo (como ASP.NET MVC) están preparados para detectar este escenario y obtener de forma automática los metadatos desde la clase buddy, pero <strong>si estamos realizando la validación de forma manual el atributo <code>[MetadataType]</code> no será tenido en cuenta</strong>. <br></br>
<br></br>
Por tanto, debemos ser nosotros los que indiquemos expresamente dónde se encuentran los metadatos, para lo que, afortunadamente, contamos con la ayuda de <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.typedescriptor.aspx"><code></code></a><a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.typedescriptor.aspx">TypeDescriptor</a>&nbsp; (definida en <code>System.ComponentModel</code>), desde donde podemos indicar el origen de los metadatos de clases simplemente registrando el proveedor desde el cual pueden ser obtenidos.<br></br>
<br></br>
El procedimiento para conseguirlo es bastante simple: creamos un proveedor de descripciones basado en metadatos utilizando la clase <a href="http://msdn.microsoft.com/es-es/library/system.componentmodel.dataannotations.associatedmetadatatypetypedescriptionprovider.aspx">AssociatedMetadataTypeTypeDescriptionProvider</a><code></code> (uuf con el nombrecito ;-)) en el que vinculamos la clase “original” con la que contiene los metadatos (la clase buddy), y a continuación añadimos dicho proveedor a la primera.<br></br>
<br></br>
Por ejemplo, para hacer que las anotaciones de la clase <code>Friend</code> se obtengan desde el tipo <code>FriendMetadata</code> podríamos incluir el siguiente código de inicialización:<br></br>
<pre ><span ><span ><span >var</span></span><span > descriptionProvider = <span >new</span>&nbsp;<span >AssociatedMetadataTypeTypeDescriptionProvider</span>(
&nbsp;&nbsp;&nbsp;&nbsp; <span >typeof</span>(<span >Friend</span>), 
&nbsp;&nbsp;&nbsp;&nbsp; <span >typeof</span>(<span >FriendMetadata</span>)
                          );
<span >TypeDescriptor</span>.AddProviderTransparent(descriptionProvider, <span >typeof</span>(<span >Friend</span>));</span></span></pre>
Otra posibilidad más genérica sería implementarlo como se muestra a continuación, donde buscamos en todo el ensamblado actual clases decoradas con el atributo <code>MetadataType</code>, registrando el proveedor de metadatos indicado en dicho atributo de forma automática:<br></br>
<pre ><span ><span ><span >private</span></span><span >&nbsp;<span >static</span>&nbsp;<span >void</span> registerBuddyClasses()
{
&nbsp;&nbsp;&nbsp; <span >var</span> buddyAssociations = 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >from</span> t <span >in</span>&nbsp;<span >Assembly</span>.GetExecutingAssembly().GetTypes()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >let</span> md = t.GetCustomAttributes(<span >typeof</span>(<span >MetadataTypeAttribute</span>), <span >false</span>)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .FirstOrDefault() <span >as</span>&nbsp;<span >MetadataTypeAttribute</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >where</span> md != <span >null</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >select</span>&nbsp;<span >new</span> { Type = t, Buddy = md.MetadataClassType };
 
&nbsp;&nbsp;&nbsp; <span >foreach</span> (<span >var</span> association <span >in</span> buddyAssociations)
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >var</span> descriptionProvider = 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >new</span>&nbsp;<span >AssociatedMetadataTypeTypeDescriptionProvider</span>(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; association.Type, association.Buddy
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >TypeDescriptor</span>.AddProviderTransparent(descriptionProvider, association.Type);
&nbsp;&nbsp;&nbsp; }
}</span></span></pre>
De esta forma, bastará con invocar el método <code>registerBuddyClasses()</code> durante la inicialización de la aplicación para que las clases buddy sean registradas de forma automática.<br></br>
<br></br>
Pero más interesante es, sin duda, que <strong>podríamos implementar nuevas fórmulas para indicar dónde se encuentran los metadatos</strong> de una clase. Por ejemplo, sería realmente sencillo modificar el método anterior para sustituir el atributo <code>MetadataType</code> por una convención de nombrado del tipo “las clases llamadas <code>FooMetadata</code> contendrán los metadatos de las clases de llamadas <code>Foo</code>”:<br></br>
<pre ><span ><span ><span >private</span></span><span >&nbsp;<span >static</span>&nbsp;<span >void</span> registerBuddyClassesUsingConventions()
{
&nbsp;&nbsp;&nbsp; <span >var</span> allAssemblyTypes = <span >Assembly</span>.GetExecutingAssembly().GetTypes().ToList();
&nbsp;&nbsp;&nbsp; <span >var</span> buddyAssociations =
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >from</span> t <span >in</span> allAssemblyTypes
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >let</span> buddy = allAssemblyTypes
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .FirstOrDefault(other =&gt; other.Name == t.Name + <span >"Metadata"</span>)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >where</span> buddy != <span >null</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >select</span>&nbsp;<span >new</span> { Type = t, Buddy = buddy };
 
&nbsp;&nbsp;&nbsp; <span >foreach</span> (<span >var</span> association <span >in</span> buddyAssociations)
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >var</span> descriptionProvider =
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >new</span>&nbsp;<span >AssociatedMetadataTypeTypeDescriptionProvider</span>(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; association.Type, association.Buddy
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >TypeDescriptor</span>.AddProviderTransparent(descriptionProvider, association.Type);
&nbsp;&nbsp;&nbsp; }
}</span></span></pre>
<h3>






¿Y si quiero usar IValidatableObject?</h3>
Cuando realizamos las validaciones de forma manual tampoco se ejecutarán por defecto las validaciones implementadas utilizando el interfaz <code><a href="http://msdn.microsoft.com/es-es/library/system.componentmodel.dataannotations.ivalidatableobject.aspx">IValidatableObject</a></code>, por lo que también debemos gestionar el escenario nosotros mismos.<br></br>
<br></br>
El interfaz <code>IValidatableObject</code> (definido <code>System.ComponentModel.DataAnnotations</code>) obliga a implementar un único método, llamado <code>Validate()</code>, que retornará una lista de objetos <code>ValidationResult</code> con los resultados de las comprobaciones.<br></br>
<br></br>
A continuación se muestra un ejemplo de implementación de este interfaz sobre una entidad:<br></br>
<pre ><span ><span ><span >public</span></span><span >&nbsp;<span >class</span>&nbsp;<span >Friend</span> : <span >IValidatableObject</span>
{
&nbsp;&nbsp;&nbsp; <span >public</span>&nbsp;<span >string</span> Name { <span >get</span>; <span >set</span>; }
&nbsp;&nbsp;&nbsp; <span >public</span>&nbsp;<span >int</span> Age { <span >get</span>; <span >set</span>; }
 
&nbsp;&nbsp;&nbsp; <span >public</span>&nbsp;<span >IEnumerable</span>&lt;<span >ValidationResult</span>&gt; Validate(<span >ValidationContext</span> validationContext)
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >if</span> (Name.Equals(<span >"albert"</span>, <span >StringComparison</span>.CurrentCultureIgnoreCase))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >yield</span>&nbsp;<span >return</span>&nbsp;<span >new</span>&nbsp;<span >ValidationResult</span>(<span >"I don't like Alberts!"</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp; }
}</span></span></pre>
Ahora, si queremos ampliar nuestro método <code>getValidationErrors()</code>, mostrado anteriormente, para que soporte también el interfaz <code>IValidatableObject</code>, podríamos realizar la siguiente implementación del mismo:<br></br>
<pre ><span ><span >&nbsp;&nbsp;&nbsp; <span >private</span>&nbsp;<span >static</span>&nbsp;<span >IEnumerable</span>&lt;<span >ValidationResult</span>&gt; getValidationErrors(<span >object</span> obj)
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >// First, data annotations</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >var</span> validationResults = <span >new</span>&nbsp;<span >List</span>&lt;<span >ValidationResult</span>&gt;();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >var</span> context = <span >new</span>&nbsp;<span >ValidationContext</span>(obj, <span >null</span>, <span >null</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >Validator</span>.TryValidateObject(obj, context, validationResults, <span >true</span>);
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >// Second, validate using IValidatableObject</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >var</span> validatable = obj <span >as</span>&nbsp;<span >IValidatableObject</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >if</span>(validatable!=<span >null</span>) 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; validationResults.AddRange(validatable.Validate(context));
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >return</span> validationResults;
&nbsp;&nbsp;&nbsp; }</span></span></pre>
De esta forma, podríamos comprobar la ejecución como sigue:<br></br>
<pre ><span ><span >&nbsp;&nbsp;&nbsp; <span >var</span> friend = <span >new</span>&nbsp;<span >Friend</span> { Age = -1, Name = <span >"albert"</span> };
&nbsp;&nbsp;&nbsp; <span >var</span> errors = getValidationErrors(friend);
&nbsp;&nbsp;&nbsp; <span >foreach</span> (<span >var</span> error <span >in</span> errors)
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >Console</span>.WriteLine(error.ErrorMessage);
&nbsp;&nbsp;&nbsp; }</span></span></pre>
<div >
The field Age must be between 0 and 120. <br></br>
<br></br>
I don’t like Alberts! </div>
En resumen, en este post hemos visto cómo utilizar las herramientas que ofrece el framework .NET para trabajar con validaciones basadas en <em>data annotations</em> de forma manual, lo que abre su ámbito de utilización a prácticamente cualquier tipo de aplicación para este marco de trabajo. Por el camino hemos repasado los mecanismos de anotaciones, y diversos escenarios como la externalización de atributos en clases buddy o el uso de la interfaz <code>IValidatableObject</code>.<br></br>
<br></br>
<a href="https://skydrive.live.com/redir.aspx?cid=c3a43a99b617d787&amp;resid=C3A43A99B617D787!278&amp;parid=C3A43A99B617D787!128&amp;authkey=!AMw05jN0Rcp-1RU">Descargar un proyecto VS2010 con el código y pruebas desde Skydrive.</a><br></br>
<br></br>
Publicado en <a href="http://www.variablenotfound.com/">Variable not found</a>.<div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/27752126-4075930113289782465?l=www.variablenotfound.com" alt=""></img></div>
<p><a href="http://feedads.g.doubleclick.net/~a/ZoO2RnVuoZr9dEoBz0NtMBPg_jk/0/da"><img src="http://feedads.g.doubleclick.net/~a/ZoO2RnVuoZr9dEoBz0NtMBPg_jk/0/di" border="0" ismap="true"></img></a><br></br>
<a href="http://feedads.g.doubleclick.net/~a/ZoO2RnVuoZr9dEoBz0NtMBPg_jk/1/da"><img src="http://feedads.g.doubleclick.net/~a/ZoO2RnVuoZr9dEoBz0NtMBPg_jk/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/vnf?a=Wu39XxmnfDk:BL-dbgU-9yM:ecdYMiMMAMM"><img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=Wu39XxmnfDk:BL-dbgU-9yM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=Wu39XxmnfDk:BL-dbgU-9yM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=Wu39XxmnfDk:BL-dbgU-9yM:4cEx4HpKnUU"><img src="http://feeds.feedburner.com/~ff/vnf?i=Wu39XxmnfDk:BL-dbgU-9yM:4cEx4HpKnUU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=Wu39XxmnfDk:BL-dbgU-9yM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/vnf?i=Wu39XxmnfDk:BL-dbgU-9yM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=Wu39XxmnfDk:BL-dbgU-9yM:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/vnf?i=Wu39XxmnfDk:BL-dbgU-9yM:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=Wu39XxmnfDk:BL-dbgU-9yM:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/vnf/~4/Wu39XxmnfDk" height="1" width="1"></img>]]></content:encoded>
		</item>
		<item>
		<title>Ingenieria de Software / Software Engineering / Project Management / Business Process Management: Microsoft Dynamics CRM Service Update</title>
		<link>http://ingsoftware.blogspot.com/2012/01/microsoft-dynamics-crm-service-update.html</link>
		<pubDate>Tue, 31 Jan 2012 20:07:00 +0000</pubDate>
		<dc:creator>JorgeBec</dc:creator>
		
	<category>microsoft</category>
		<guid>http://ingsoftware.blogspot.com/2012/01/microsoft-dynamics-crm-service-update.html</guid>
		<description><![CDATA[Me da gusto saber que en el próximo Service Update de CRM se podrá accesar a Dynamics CRM con los Navegadores Safari, Firefox y Chrome  En el siguiente link lo nuevo que se presento en el Service Update de Noviembre  http://blog.sonomapartners.com/20...]]></description>
			<content:encoded><![CDATA[<p>Me da gusto saber que en el próximo Service Update de CRM se podrá accesar a Dynamics CRM con los Navegadores Safari, Firefox y Chrome</p>  <p>En el siguiente link lo nuevo que se presento en el Service Update de Noviembre</p>  <p><a title="http://blog.sonomapartners.com/2012/01/whats-new-in-the-microsoft-dynamics-crm-november-2011-service-update.html?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+typepad%2Fsonoma+%28Sonoma+Partners+Microsoft+CRM+Blog%29&amp;utm_content=Bloglines" href="http://blog.sonomapartners.com/2012/01/whats-new-in-the-microsoft-dynamics-crm-november-2011-service-update.html?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+typepad%2Fsonoma+%28Sonoma+Partners+Microsoft+CRM+Blog%29&amp;utm_content=Bloglines">http://blog.sonomapartners.com/2012/01/whats-new-in-the-microsoft-dynamics-crm-november-2011-service-update.html?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+typepad%2Fsonoma+%28Sonoma+Partners+Microsoft+CRM+Blog%29&amp;utm_content=Bloglines</a></p>  <div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/9995896-3107091551537683544?l=ingsoftware.blogspot.com" alt=""></img></div>]]></content:encoded>
		</item>
		<item>
		<title>Bitácora de Javier Gutiérrez Chamorro (Guti) » Programación: Avances en la informática personal (I)</title>
		<link>http://guti.bitacoras.com/avances-en-la-informatica-personal-i/1727</link>
		<pubDate>Tue, 31 Jan 2012 11:42:54 +0000</pubDate>
		<dc:creator>Javier Gutiérrez Chamorro (Guti)</dc:creator>
		
	<category>Programación</category>
	<category>Internet</category>
	<category>Informática</category>
	<category>Software</category>
	<category>juegos</category>
	<category>hardware</category>
	<category>Retro</category>
		<guid>http://guti.bitacoras.com/avances-en-la-informatica-personal-i/1727</guid>
		<description><![CDATA[La informática es la disciplina con avance más rápido que ha existido, tanto es así que todos aquellos que seáis de mi generación, habréis podido ser testigos en primera persona de sus orígenes a principios de los años 80, hasta nuestra situación actual en 2012. Bien es cierto que a simple vista la cosa no [...]<br/><br/><b>Art&#237;culos relacionados:</b><br/> <a href='http://guti.bitacoras.com/avances-con-smetar/248' rel='bookmark' title='Avances con SMETAR'>Avances con SMETAR</a><br/> <a href='http://guti.bitacoras.com/inform-tica-y-coches/976' rel='bookmark' title='Informática y coches'>Informática y coches</a><br/> <a href='http://guti.bitacoras.com/record-personal-en-operation-wolf/1314' rel='bookmark' title='Record personal en Operation Wolf'>Record personal en Operation Wolf</a><br/> ]]></description>
			<content:encoded><![CDATA[La informática es la disciplina con avance más rápido que ha existido, tanto es así que todos aquellos que seáis de mi generación, habréis podido ser testigos en primera persona de sus orígenes a principios de los años 80, hasta nuestra situación actual en 2012. Bien es cierto que a simple vista la cosa no [...]<br/><br/><b>Art&iacute;culos relacionados:</b><br/> <a href='http://guti.bitacoras.com/avances-con-smetar/248' rel='bookmark' title='Avances con SMETAR'>Avances con SMETAR</a><br/> <a href='http://guti.bitacoras.com/inform-tica-y-coches/976' rel='bookmark' title='Informática y coches'>Informática y coches</a><br/> <a href='http://guti.bitacoras.com/record-personal-en-operation-wolf/1314' rel='bookmark' title='Record personal en Operation Wolf'>Record personal en Operation Wolf</a><br/> ]]></content:encoded>
		</item>
		<item>
		<title>xailer.info (esp): CheckMenu</title>
		<link>http://xailer.info/esp/?p=827</link>
		<pubDate>Tue, 31 Jan 2012 10:00:13 +0000</pubDate>
		<dc:creator>José Lalín</dc:creator>
		
	<category>Componentes</category>
	<category>Xailer 2.5</category>
	<category>CheckMenu</category>
		<guid>http://xailer.info/esp/?p=827</guid>
		<description><![CDATA[El control TCheckMenu representa un control tipo menú utilizando botones Checkbox y es prácticamente idéntico en funcionalidad al control TRadioMenu nativo del IDE con la diferencia que aquí podemos seleccionar varias opciones.


Las únicas diferencias a tener en cuenta son dos:

Se añade una propiedad aChecked que sirve tanto para establecer qué elementos están seleccionados cuando se [...]]]></description>
			<content:encoded><![CDATA[<p>El control <em>TCheckMenu </em>representa un control tipo menú utilizando botones <em>Checkbox </em>y es prácticamente idéntico en funcionalidad al control <em>TRadioMenu </em>nativo del IDE con la diferencia que aquí podemos seleccionar varias opciones.</p>
<p><span id="more-827"></span></p>
<p ><img class="size-full wp-image-828 aligncenter" title="CheckMenu" src="http://xailer.info/esp/wp-content/uploads/2012/01/CheckMenu.png" alt="CheckMenu" width="189" height="122" /></p>
<p>Las únicas diferencias a tener en cuenta son dos:</p>
<ul>
<li>Se añade una propiedad aChecked que sirve tanto para establecer qué elementos están seleccionados cuando se crea el control y para obtener la lista de elementos que se han seleccionado.</li>
<li>El evento OnChange( oSender, nIndex, lChecked ) añade un nuevo parámetro lChecked que informa si el elemento que acaba de cambiar está seleccionado o no.</li>
</ul>
<p>En el <a href="http://www.xailer.com/download?file=52">ZIP </a>se incluye la DLL y la librería para Xailer 2.5</p>
]]></content:encoded>
		</item>
		<item>
		<title>Variable not found: Enlaces interesantes 69</title>
		<link>http://feedproxy.google.com/~r/vnf/~3/JOq0DjNEN4c/enlaces-interesantes-69.html</link>
		<pubDate>Tue, 31 Jan 2012 07:53:00 +0000</pubDate>
		<dc:creator>José M. Aguilar</dc:creator>
		
	<category>enlaces</category>
		<guid>http://feedproxy.google.com/~r/vnf/~3/JOq0DjNEN4c/enlaces-interesantes-69.html</guid>
		<description><![CDATA[Estos son los enlaces publicados en Variable not found en Facebook y Twitter del 16 al 29 de enero de 2012. Espero que os resulten interesantes. :-)

.Net

Introducing Dragonfly – another .NET HTTP server       Louis DeJardin 
Inside the Concurrent C...]]></description>
			<content:encoded><![CDATA[<a href="http://lh5.ggpht.com/-gVh5uOH2UQI/TyedcmXngwI/AAAAAAAABvc/d9n68quaHoY/s1600-h/image7_thumb_thumb_thumb_thumb2.png"><img align="right" alt="Enlaces interesantes" border="0" height="129" src="http://lh5.ggpht.com/-kQV8VQ_AqZU/TyeddgEbNUI/AAAAAAAABvk/fslgf51tsn0/image7_thumb_thumb_thumb_thumb_thumb.png?imgmax=800"  title="Enlaces interesantes" width="172"></img></a>Estos son los enlaces publicados en <a href="http://www.facebook.com/variablenotfound">Variable not found en Facebook</a> y <a href="http://twitter.com/jmaguilar">Twitter</a> del 16 al 29 de enero de 2012. Espero que os resulten interesantes. :-)<br></br>
<a name="more"></a><br></br>
<h4>

.Net</h4>
<ul>
<li><a href="http://whereslou.com/2012/01/24/introducing-dragonfly-another-net-http-server"><strong>Introducing Dragonfly – another .NET HTTP server</strong></a>       <br></br>Louis DeJardin </li>
<li><a href="http://geekswithblogs.net/simonc/archive/2012/01/24/inside-the-concurrent-collections-concurrentqueue.aspx"><strong>Inside the Concurrent Collections: ConcurrentQueue</strong></a>       <br></br>Simon Cooper </li>
<li><strong><a href="http://blogs.msdn.com/b/csharpfaq/archive/2012/01/23/using-async-for-file-access-alan-berman.aspx">Using Async for File Access</a>         </strong>C# Team </li>
<li><strong><a href="http://blogs.microsoft.co.il/blogs/sasha/archive/2012/01/20/aggressive-inlining-in-the-clr-4-5-jit.aspx">Aggressive Inlining in the CLR 4.5 JIT</a></strong>       <br></br>Sasha Goldshtein </li>
<li><strong><a href="http://blogs.msdn.com/b/ericlippert/archive/2012/01/16/what-is-the-defining-characteristic-of-a-local-variable.aspx">What is the defining characteristic of a local variable?</a></strong>       <br></br>Eric Lippert </li>
<li><a href="http://geekswithblogs.net/BlackRabbitCoder/archive/2012/01/12/c.net-little-pitfalls-stopwatch-ticks-are-not-timespan-ticks.aspx" title="Title of this entry"><strong>C#/.NET Little Pitfalls: Stopwatch Ticks are not TimeSpan Ticks</strong></a>       <br></br>James Michael Hare </li>
<li><a href="http://geekswithblogs.net/simonc/archive/2012/01/12/inside-the-concurrent-collections-concurrentstack.aspx" title="Title of this entry"><strong>Inside the Concurrent Collections: ConcurrentStack</strong></a>       <br></br>Simon Cooper       <ul></ul>
</li>
</ul>
<h4>

Asp.net</h4>
<ul>
<li><a href="http://www.matthidinger.com/archive/2012/01/23/adding-rich-selector-support-for-mvc.aspx"><strong>Adding rich Selector support for MVC</strong></a>       <br></br>Matt Hidinger </li>
<li><a href="http://www.collectivematters.com/2012/01/solving-real-world-theming-challenges-with-mvc4-and-sass/"><strong>Solving Real-world Theming Challenges with MVC4 and Sass</strong></a>       <br></br>Harvey Kandola </li>
<li><strong><a href="http://blogs.msdn.com/b/cdndevs/archive/2012/01/23/javascript-and-css-minifying-bundling-with-the-microsoft-web-optimization-nuget-package.aspx">Javascript and CSS Minifying/Bundling with the Microsoft.Web.Optimization Nuget package</a></strong>       <br></br>Maxime Rouiller </li>
<li><strong><a href="http://desarrolloweb.com/articulos/validaciones-propias-aspnet-mvc-dotnet.html">Validaciones propias en ASP.NET MVC</a></strong>       <br></br>Eduard Tomás       <ul></ul>
</li>
<li><strong><a href="http://blogs.msdn.com/b/chunliu/archive/2012/01/20/the-flowchart-of-the-ie-rendering-modes.aspx">The flowchart of the IE rendering modes</a></strong>       <br></br>Chun Liu </li>
<li><strong><a href="http://weblogs.asp.net/jeff/archive/2012/01/23/pop-forums-v9-2-posted-to-codeplex-with-new-lanuages-post-voting-and-the-scoring-game.aspx">POP Forums v9.2 posted to CodePlex, with new languages, post voting and the scoring game</a></strong>       <br></br>Jeff Putz </li>
<li><strong><a href="http://www.codefrenzy.net/2012/01/23/asp-net-response-redirect/">ASP.NET Response.Redirect</a></strong>       <br></br>Annie Luxton </li>
<li><strong><a href="http://code-inside.de/blog-in/2012/01/23/fix-the-value-x-is-not-valid-for-foo-in-asp-net-mvc">Fix: the value ‘x’ is not valid for Foo in ASP.NET MVC</a></strong>       <br></br>Code Inside Team       <ul></ul>
</li>
<li><a href="http://mrubino.net/2012/01/23/deploy-web-con-configuracion-dinamic/"><strong>Web Deploy – config Transformation</strong></a>       <br></br>Marc Rubiño </li>
<li><a href="http://www.jasoft.org/Blog/post/Como-simular-otros-navegadores-para-probar-desarrollos-Web.aspx" title="Cómo simular otros navegadores para probar desarrollos Web"><strong>Cómo simular otros navegadores para probar desarrollos Web</strong></a>       <br></br>José Manuel Alarcón       <ul></ul>
</li>
<li><strong><a href="http://weblogs.asp.net/jgalloway/archive/2012/01/17/10-things-asp-net-developers-should-know-about-web-config-inheritance-and-overrides.aspx">10 Things ASP.NET Developers Should Know About Web.config Inheritance and Overrides</a></strong>       <br></br>Jon Galloway </li>
<li><a href="http://www.jasoft.org/Blog/post/Como-obtener-rutas-absolutas-en-ASPNET.aspx" title="Cómo obtener rutas absolutas en ASP.NET"><strong>Cómo obtener rutas absolutas en ASP.NET</strong></a>       <br></br>José Manuel Alarcón </li>
<li><strong><a href="http://mrubino.net/2012/01/17/push-con-singalr/">Push con SingalR</a></strong>       <br></br>Marc Rubiño </li>
<li><a href="http://blog.maartenballiauw.be/post/2012/01/20/Tracking-API-usage-with-Google-Analytics.aspx" title="Tracking API usage with Google Analytics"><strong>Tracking API usage with Google Analytics</strong></a>       <br></br>Maarten Balliauw       <ul></ul>
</li>
<li><strong><a href="http://gregorsuttie.com/2012/01/15/mvc-get-some-help/">MVC – get some help</a></strong>       <br></br>Gregor Suttie </li>
</ul>
<h4>

Azure / Cloud</h4>
<ul>
<li><strong><a href="http://www.estoyenlanube.com/release-de-sql-azure-importexport/">Release de SQL Azure Import/Export</a></strong>       <br></br>Ibon Landa </li>
<li><strong><a href="http://blogs.msdn.com/b/scicoria/archive/2012/01/19/making-windows-azure-drive-letter-persistent.aspx">Making Windows Azure Drive Letter Persistent</a></strong>       <br></br>Shawn Cicoria       <ul></ul>
</li>
<li><strong><a href="http://weblogs.asp.net/scottgu/archive/2012/01/19/getting-started-with-windows-azure.aspx">Getting Started with Windows Azure</a> </strong>      <br></br>Scott Guthrie </li>
</ul>
<h4>

Conceptos</h4>
<ul>
<li><a href="http://sebys.com.ar/2012/01/09/gof-singleton/"><strong>Gof – Singleton</strong></a>       <br></br>Sebis </li>
</ul>
<h4>

Data access</h4>
<ul>
<li><strong><a href="http://thedatafarm.com/blog/data-access/what-do-you-want-to-see-in-entity-framework/">What do you want to see in Entity Framework?</a></strong>       <br></br>Julie Lerman </li>
<li><strong><a href="http://www.heidisql.com/">HeidiSQL: Windows based interface for managing MySQL and Microsoft SQL databases</a></strong>       <br></br>Ansgar Becker </li>
<li><strong><a href="http://www.codeproject.com/Articles/316816/RaptorDB-The-Key-Value-Store-V2">RaptorDB - The Key Value Store V2</a></strong>       <br></br>Mehdi Gholam </li>
<li><strong><a href="http://geeks.ms/blogs/jtorrecilla/archive/2012/01/18/orm-orapoco-trabajando-contra-oracle.aspx">OraPoco: Trabajando contra Oracle</a></strong>       <br></br>Javier Torrecilla </li>
<li><a href="http://blogs.msdn.com/b/diego/archive/2012/01/15/why-entity-framework-vnext-will-be-ef5-and-nothing-else.aspx"><strong>Why Entity Framework vNext will be EF5 and nothing else</strong></a>       <br></br>Diego B. Vega&nbsp; </li>
</ul>
<h4>

Html/Css/Javascript</h4>
<ul>
<li><strong><a href="http://net.tutsplus.com/tutorials/javascript-ajax/from-jquery-to-javascript-a-reference/">From jQuery to JavaScript: A Reference</a></strong>       <br></br>Jeffrey Way </li>
<li><strong><a href="http://lostechies.com/derickbailey/2012/01/24/some-thoughts-on-functional-javascript/">Some Thoughts On Functional JavaScript</a></strong>       <br></br>Derick Bailey       <ul></ul>
</li>
<li><strong><a href="http://www.elijahmanor.com/2012/01/find-jquery-bug-2-point-of-no-return.html">Find the jQuery Bug #2: Point of No Return</a> </strong>      <br></br>Elijah Manor </li>
<li><a href="http://blog.boyet.com/blog/javascriptlessons/javascript-for-c-developers-coercion/"><strong>JavaScript for C# developers: coercion</strong></a>       <br></br>Julian M. Bucknall       <ul></ul>
</li>
<li><strong><a href="http://geeks.ms/blogs/gperez/archive/2012/01/25/modernizr-ejemplo-pr-225-ctico-2-utilizando-border-radius-elemento-date-y-atributo-required.aspx">Modernizr–Ejemplo práctico 2 : Utilizando Border Radius, elemento date y atributo required</a></strong>       <br></br>Gonzalo Pérez </li>
<li><strong><a href="http://html5doctor.com/server-sent-events/">Server-Sent Events</a> </strong>      <br></br>Remy Sharp </li>
<li><strong><a href="http://dotnetslackers.com/articles/aspnet/Using-HTML5-Web-Storage-in-ASP-NET.aspx">Using HTML5 Web Storage in ASP.NET</a></strong>       <br></br>Bipin Joshi </li>
<li><a href="http://www.etnassoft.com/2012/01/24/creando-objetos-y-aplicaciones-configurables-en-javascript/" title="Enlace permanente a Creando objetos y aplicaciones configurables en Javascript"><strong>Creando objetos y aplicaciones configurables en Javascript</strong></a>       <br></br>Carlos Benítez       <ul></ul>
</li>
<li><strong><a href="http://www.jquery4u.com/tools/10-excellent-free-rich-text-editors/">10 Excellent Free Rich-Text Editors</a></strong>       <br></br>jQuery4u </li>
<li><a href="http://freshbrewedcode.com/derekgreer/2012/01/22/solid-javascript-the-dependency-inversion-principle/" title="Permanent Link to SOLID JavaScript- The Dependency Inversion Principle"><strong>SOLID JavaScript- The Dependency Inversion Principle</strong></a>       <br></br>Derek Greer       <ul></ul>
</li>
<li><strong><a href="http://www.kirupa.com/html5/easing_functions_css3.htm">Easing Functions in CSS3</a></strong>       <br></br>Kirupa Chinnathambi </li>
<li><strong><a href="http://jclaes.blogspot.com/2012/01/how-wikipedia-uses-html5-to-save.html">How Wikipedia uses HTML5 to save bandwidth</a></strong>       <br></br>Jef Claes       <ul></ul>
</li>
<li><a href="http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/"><strong>The Top 10 Javascript MVC Frameworks Reviewed</strong></a>       <br></br>Gordon L. Hempton </li>
<li><a href="http://css3.bradshawenterprises.com/" title="Using CSS3 Transitions, Transforms and Animation"><strong>Using CSS3 Transitions, Transforms and Animation</strong></a>       <br></br>Rich Bradshaw </li>
</ul>
<h4>

Visual Studio/Complementos</h4>
<ul>
<li><strong><a href="http://blogs.jetbrains.com/dotnet/2012/01/importing-exporting-templates-and-patterns-in-resharper-61/">Importing / Exporting Templates and Patterns in ReSharper 6.1</a></strong>       <br></br>Hadi Hariri </li>
<li><a href="http://www.alvinashcraft.com/2012/01/23/c-resharper-awesome-tip-8-extract-class-from-parameters/"><strong>C# + ReSharper = Awesome: Tip #8 – Extract Class From Parameters</strong></a>       <br></br>Alvin Ashcraft </li>
<li><a href="http://www.alvinashcraft.com/2012/01/20/c-resharper-awesome-tip-7move-string-to-resource/"><strong>C# + ReSharper = Awesome: Tip #7–Move String to Resource</strong></a>       <br></br>Alvin Ashcraft's </li>
<li><strong><a href="http://geeks.ms/blogs/jorge/archive/2012/01/23/stylecop-v4-7-6-0-disponible.aspx">StyleCop v4.7.6.0 disponible</a></strong>       <br></br>Jorge Serrano&nbsp;&nbsp; </li>
</ul>
<h4>

Otros</h4>
<ul>
<li><a href="http://www.troyhunt.com/2012/01/breaking-captcha-with-automated-humans.html" title="Breaking CAPTCHA with automated humans"><strong>Breaking CAPTCHA with automated humans</strong></a>       <br></br>Troy Hunt </li>
<li><strong><a href="http://googlecode.blogspot.com/2012/01/lets-make-tcp-faster.html">Let's make TCP faster</a></strong>       <br></br>Yuchung Cheng </li>
<li><a href="http://jmalarcon.es/post/El-Cargo-Cult-de-las-pequenas-empresas.aspx"><strong>El "Cargo Cult" de las pequeñas empresas</strong></a>       <br></br>José Manuel Alarcón </li>
<li><a href="http://jmalarcon.es/post/El-efecto-Mateo-y-su-influencia.aspx" title="El efecto Mateo y su influencia"><strong>El efecto Mateo y su influencia</strong></a>       <br></br>José Manuel Alarcón </li>
</ul>
Y no olvidéis que podéis seguir esta información en vivo y en directo desde <a href="http://www.facebook.com/variablenotfound">Variable not found en Facebook</a>, o a través de <a href="http://twitter.com/jmaguilar">Twitter</a>.   <br></br>
<br></br>
Publicado en <a href="http://www.variablenotfound.com/">Variable not found</a><div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/27752126-8834948775836902214?l=www.variablenotfound.com" alt=""></img></div>
<p><a href="http://feedads.g.doubleclick.net/~a/M0arkBNm-h4Dt8TaHBCIAYGF73Q/0/da"><img src="http://feedads.g.doubleclick.net/~a/M0arkBNm-h4Dt8TaHBCIAYGF73Q/0/di" border="0" ismap="true"></img></a><br></br>
<a href="http://feedads.g.doubleclick.net/~a/M0arkBNm-h4Dt8TaHBCIAYGF73Q/1/da"><img src="http://feedads.g.doubleclick.net/~a/M0arkBNm-h4Dt8TaHBCIAYGF73Q/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/vnf?a=JOq0DjNEN4c:8hHRIyp4svg:ecdYMiMMAMM"><img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=JOq0DjNEN4c:8hHRIyp4svg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=JOq0DjNEN4c:8hHRIyp4svg:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=JOq0DjNEN4c:8hHRIyp4svg:4cEx4HpKnUU"><img src="http://feeds.feedburner.com/~ff/vnf?i=JOq0DjNEN4c:8hHRIyp4svg:4cEx4HpKnUU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=JOq0DjNEN4c:8hHRIyp4svg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/vnf?i=JOq0DjNEN4c:8hHRIyp4svg:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=JOq0DjNEN4c:8hHRIyp4svg:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/vnf?i=JOq0DjNEN4c:8hHRIyp4svg:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=JOq0DjNEN4c:8hHRIyp4svg:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/vnf/~4/JOq0DjNEN4c" height="1" width="1"></img>]]></content:encoded>
		</item>
		<item>
		<title>Koalite's blog: Tutorial jQuery Mobile + Knockout (I): Sentando las bases</title>
		<link>http://feedproxy.google.com/~r/KoalitesBlog/~3/39l6vnl6mGE/</link>
		<pubDate>Mon, 30 Jan 2012 03:53:36 +0000</pubDate>
		<dc:creator>Juanma</dc:creator>
		
	<category>JavaScript</category>
	<category>tutorial</category>
	<category>development</category>
	<category>jquerymobile</category>
	<category>knockoutjs</category>
		<guid>http://feedproxy.google.com/~r/KoalitesBlog/~3/39l6vnl6mGE/</guid>
		<description><![CDATA[<script type="text/javascript">
				  (function() {
				    var po = document.createElement("script"); po.type = "text/javascript"; po.async = true;
				    po.src = "https://apis.google.com/js/plusone.js";
				    var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(po, s);
				  })();
				</script>Tras la buena acogida que tuvo el tutorial de nodejs y express, me he decidido a preparar otro tutorial que sirva de introducción para un par de librerías con las que he estado jugando últimamente. Igual que en el anterior tutorial, quiero dejar claro que esto es sólo una pequeña introducción a dos librerías que [...]
<strong>Posts relacionados:</strong><ol>
<li><a href='http://blog.koalite.com/2011/11/tutorial-node-js-express-jquery-iii-usando-jquery/' rel='bookmark' title='Tutorial node.js + express + jquery (III): Usando jQuery'>Tutorial node.js + express + jquery (III): Usando jQuery</a></li>
<li><a href='http://blog.koalite.com/2011/11/tutorial-node-js-express-jquery-iv-conclusiones-y-proximos-pasos/' rel='bookmark' title='Tutorial node.js + express + jquery (IV): Conclusiones y próximos pasos'>Tutorial node.js + express + jquery (IV): Conclusiones y próximos pasos</a></li>
<li><a href='http://blog.koalite.com/2011/11/tutorial-node-js-express-jquery-i-creando-la-aplicacion/' rel='bookmark' title='Tutorial node.js + express + jquery (I): Creando la aplicación'>Tutorial node.js + express + jquery (I): Creando la aplicación</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Tras la buena acogida que tuvo el <a href="http://blog.koalite.com/2011/11/tutorial-node-js-express-jquery-i-creando-la-aplicacion/" title="Tutorial node.js + express + jquery (I): Creando la aplicación" >tutorial de nodejs y express</a>, me he decidido a preparar otro tutorial que sirva de introducción para un par de librerías con las que he estado jugando últimamente.</p>
<p>Igual que en el anterior tutorial, quiero dejar claro que esto es sólo una pequeña introducción a dos librerías que me parecen útiles. No se trata de un catálogo de buenas prácticas y habrá muchos puntos que puedan (y deban) ser mejorados.</p>
<p>En este caso vamos a crear una pequeña aplicación web para dispositivos móviles usando <a href="http://jquerymobile.com/" >jQuery Mobile</a> y <a href="http://knockoutjs.com/" >Knockout</a>. Como creo que <a href="http://blog.koalite.com/2011/08/%C2%BFhacen-los-frameworks-tontos-a-los-desarrolladores/" >es importante conocer las bases</a> para poder entender lo que estamos haciendo, antes de empezar a implementar nada vamos a presentar a nuestros nuevos amigos.</p>
<h3>jQuery Mobile</h3>
<p><a href="http://jquerymobile.com/" >jQuery Mobile</a> es un framework que nos permite crear aplicaciones para dispositivos móviles. Por tanto, está optimizado para su uso con pantallas de pequeño tamaño e interfaces táctiles encargándose de ajustar el interfaz de usuario de los controles estándar html para que sean más atractivos y manejables en un entorno móvil.</p>
<p>Se ejecuta por completo en el lado cliente, en este caso, el browser del dispositivo. Para emplearlo, debemos añadir lo siguiente a nuestra página web:</p>
<pre class="brush:html">
	<script type="text/javascript" src="http://feedproxy.google.com/~r/KoalitesBlog/~3/39l6vnl6mGE/js/jquery-1.7.min.js"></script>
	<link rel="stylesheet" href="http://feedproxy.google.com/~r/KoalitesBlog/~3/39l6vnl6mGE/css/jquery.mobile-1.0.min.css" />
	<script type="text/javascript" src="http://feedproxy.google.com/~r/KoalitesBlog/~3/39l6vnl6mGE/js/jquery.mobile-1.0.min.js"></script>
</pre>
<p>Podemos usar la versión descargada o enlazar directamente a una versión online, tal y como explican en la <a href="http://jquerymobile.com/download/" >su página de descarga</a>.</p>
<p>jQuery Mobile se basa en la asignación de roles a los distintos elementos html para atribuirles determinadas funciones dentro de la aplicación. A partir de estos roles, se ajusta el aspecto del elemento. Para asignar los roles a los elementos se usa el atributo <code>data-role</code>:</p>
<pre class="brush:html">
	<div id="home" data-role="page"></div>
</pre>
<p>Una aplicación desarrollada con jQuery Mobile se estructura alrededor del concepto de <em>página</em>. Una <em>página</em> no es más que un <code>div</code> que tiene asignado el rol <code>page</code>, como en el ejemplo anterior. En un único documento html podremos tener varias <em>páginas</em> simplemente añadiendo varios <code>div</code>s con el atributo <code>data-role="page"</code>, y jQueryMobile se encargará de mostrar en cada momento únicamente el <code>div</code> correspondiente a la <em>página</em> que esté activa.</p>
<p>Además del rol usado para marcar las <em>páginas</em>, existen otros roles muy útiles como <code>header</code>, <code>footer</code>, etc.  que permiten representar otros elementos dentro de la <em>página</em>, o <code>listview</code>, <code>button</code>, etc. que se usan para crear controles con los que el usuario puede interactuar.</p>
<p>Si quieres conocer en profundidad las opciones que ofrece jQuery Mobile, te recomiendo que <a href="http://jquerymobile.com/test/" >consultes su documentación</a>.</p>
<h3>Knockout</h3>
<p><a href="http://knockoutjs.com/" >Knockout</a> es una librería diseñada para aplicar cómodamente el patrón <abbr title="Model-View-ViewModel">MVVM</abbr> en aplicaciones javascript. Al igual que jQuery Mobile se ejecuta por completo en el browser por lo que deberemos incluirla en el código de nuestras páginas:</p>
<pre class="brush:html">
	<script type="text/javascript" src="http://feedproxy.google.com/~r/KoalitesBlog/~3/39l6vnl6mGE/js/knockout-2.0.0.js"></script>
</pre>
<p>Para poder trabajar con Knockout es fundamental conocer el patrón <a href="http://en.wikipedia.org/wiki/Model_View_ViewModel" >Model-View-ViewModel</a>. Resumiéndolo (mucho) podríamos decir que se basa en organizar la aplicación en torno a 3 conceptos:</p>
<ul>
<li><strong>Model</strong>. Es el modelo completo de la aplicación, donde reside la lógica de negocio y todas esas cosas importantes. Knockout no se mete en esta parte y puedes implementarla como quieras. Lo más habitual es que resida en un servidor y la aplicación se comunique con él a través de AJAX.</li>
<li><strong>View</strong>. La vista, dedicada únicamente a mostrar información. No contiene ningún tipo de lógica, ni siquiera lógica relacionada con el interfaz de usuario, porque para eso está la última parte del trío.</li>
<li><strong>ViewModel</strong>. El modelo de presentación, que se encarga de <em>adaptar</em> el modelo de la aplicación a las necesidades de la vista y contiene además toda la lógica relacionada con el interfaz de usuario, como por ejemplo cuándo se debe habilitar un control o qué hay que hacer cuando se pulsa un botón.</li>
</ul>
<p>Knockout nos ofrece una manera muy sencilla de enlazar <code>View</code> y <code>ViewModel</code> a través de <em>data binding</em>. Este <em>data binding</em> se hace de forma declarativa usando atributos <code>data-bind</code>:</p>
<pre class="brush:html">
    <h1 data-bind="text: customerName"></h1>
</pre>
<p>Las posibilidades que ofrece Knockout para realizar el <em>data binding</em> son de lo más variado y podéis consultarlas en la <a href="http://knockoutjs.com/documentation/introduction.html" >documentación de Knockout</a>.</p>
<p>Para que funcione esto del <em>data binding</em> es fundamental poder detectar los cambios en los valores de los controles para propagarlos al <code>ViewModel</code>, pero también es necesario poder detectar los cambios en el <code>ViewModel</code> para propagarlos a la vista. En este aspecto Knockout cuenta con su propia implementación del <a href="http://en.wikipedia.org/wiki/Observer_pattern" >patrón observer</a>, a través de funciones como <code>ko.observable</code>.</p>
<h3>¿Cuándo empezamos?</h3>
<p>En el siguiente post veremos cómo es la aplicación de ejemplo que vamos a hacer en este tutorial y prepararemos la estructura de <em>páginas</em> de jQuery Mobile que vamos a tener.</p>
<div class="trackable_sharing"><div class="trackable_sharing_text"><b><br/><br/><br/>Compartir enlace:
</b></div><a href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fblog.koalite.com%2F2012%2F01%2Ftutorial-jquery-mobile-knockout-i-sentando-las-bases%2F"  title="Facebook"  onclick="that=this;_gaq.push(['_trackEvent','SocialSharing','Facebook','http://blog.koalite.com/2012/01/tutorial-jquery-mobile-knockout-i-sentando-las-bases/']); _trackableshare_window = window.open(this.href,'share','menubar=0,resizable=1,width=500,height=350'); _trackableshare_window.focus(); return false;"><img align="absmiddle" src="http://blog.koalite.com/wp-content/plugins/trackable-social-share-icons/buttons/f2//facebook.png" alt="Facebook" width="36" height="36"></a> <a href="http://twitter.com/share?url=http%3A%2F%2Fblog.koalite.com%2F2012%2F01%2Ftutorial-jquery-mobile-knockout-i-sentando-las-bases%2F&text=Tutorial+jQuery+Mobile+%2B+Knockout+%28I%29%3A+Sentando+las+bases"  title="Twitter"  onclick="that=this;_gaq.push(['_trackEvent','SocialSharing','Twitter','http://blog.koalite.com/2012/01/tutorial-jquery-mobile-knockout-i-sentando-las-bases/']); _trackableshare_window = window.open(this.href,'share','menubar=0,resizable=1,width=500,height=350'); _trackableshare_window.focus(); return false;"><img align="absmiddle" src="http://blog.koalite.com/wp-content/plugins/trackable-social-share-icons/buttons/f2//twitter.png" alt="Twitter" width="36" height="36"></a> <a href="mailto:?subject=Check%20out%20http%3A%2F%2Fblog.koalite.com%2F2012%2F01%2Ftutorial-jquery-mobile-knockout-i-sentando-las-bases%2F"  title="Email" onclick="that=this;_gaq.push(['_trackEvent','SocialSharing','Email','http://blog.koalite.com/2012/01/tutorial-jquery-mobile-knockout-i-sentando-las-bases/']); "><img align="absmiddle" src="http://blog.koalite.com/wp-content/plugins/trackable-social-share-icons/buttons/f2//email.png" alt="Email" width="36" height="36"></a> <br /><g:plusone annotation="none"></g:plusone></div><p><strong>Posts relacionados:</strong></p><ol>
<li><a href='http://blog.koalite.com/2011/11/tutorial-node-js-express-jquery-iii-usando-jquery/' rel='bookmark' title='Tutorial node.js + express + jquery (III): Usando jQuery'>Tutorial node.js + express + jquery (III): Usando jQuery</a></li>
<li><a href='http://blog.koalite.com/2011/11/tutorial-node-js-express-jquery-iv-conclusiones-y-proximos-pasos/' rel='bookmark' title='Tutorial node.js + express + jquery (IV): Conclusiones y próximos pasos'>Tutorial node.js + express + jquery (IV): Conclusiones y próximos pasos</a></li>
<li><a href='http://blog.koalite.com/2011/11/tutorial-node-js-express-jquery-i-creando-la-aplicacion/' rel='bookmark' title='Tutorial node.js + express + jquery (I): Creando la aplicación'>Tutorial node.js + express + jquery (I): Creando la aplicación</a></li>
</ol><img src="http://feeds.feedburner.com/~r/KoalitesBlog/~4/39l6vnl6mGE" height="1" width="1"/>]]></content:encoded>
		</item>
		<item>
		<title>Escuela De Codigo: CoffeeScript, El primer paso</title>
		<link>http://escueladecodigo.com/coffeescript-el-primer-paso/</link>
		<pubDate>Mon, 30 Jan 2012 01:11:54 +0000</pubDate>
		<dc:creator>Hugo Gonzalez</dc:creator>
		
	<category>Tutoriales</category>
		<guid>http://escueladecodigo.com/coffeescript-el-primer-paso/</guid>
		<description><![CDATA[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. [...]]]></description>
			<content:encoded><![CDATA[<p ><a href="http://escueladecodigo.com/wp-content/uploads/2012/01/cat_looking_at_coffee.jpg"><img class="alignright  wp-image-1518" title="cat_looking_at_coffee" src="http://escueladecodigo.com/wp-content/uploads/2012/01/cat_looking_at_coffee.jpg" alt="" width="345" height="234" /></a>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.</p>
<p >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.</p>
<p >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.</p>
<p >y así fue como nació CoffeeScript,un lenguaje de programación que se escribe bonito y genera Javascript de toda la vida.</p>
<p ><span id="more-1419"></span></p>
<h2>Instalación</h2>
<p >Para instalar Coffeescript, necesitamos primeramente instalar<a href="http://nodejs.org/" > Node.js</a> y <a href="http://npmjs.org/" >npm</a>, una vez ya lo hallas hecho solo ejecuta en tu terminal favorita</p>
<p ><style type="text/css">


/* *************************************************** */
/* WordPress default theme "twenty-ten" compatibility: */
/* FIXME: Is there a way to limit these changes to pygmentize_wpbTa2  */
/*        without editing the WordPress theme directly? */
/* *************************************************** */

#content pre {
  /* The background: transparent is needed to work with WordPress:*/
  background: transparent;
  /* Default WordPress style has a big fat <pre> margin-bottom: */
  margin-bottom: 20px;

  /*color: #333333;*/
  font-size: .9em; 
  line-height: 1.25em;
}

#content table {
}

#content table {
	border: 1px solid #e7e7e7;
    margin: 0 0 0 0;
	text-align: left;
	width: 100%;
}
#content tr th,
#content thead th {
	color: #888;
	font-size: 12px;
	font-weight: bold;
	line-height: 18px;
	padding: 0px;
}
#content tr td {
	border: 0px;
	padding: 0px;
	margin: 0px;
    margin-bottom: 0px;
    padding-bottom: 0px;

}

/* *************************************************** */
/* *************************************************** */

/* Standard fixes to the default output: */

/* Set the tab width in "ch" character units: */
.pygmentize_wpbTa2 .tabspan {
  display: inline-block;
  width: 4ch;
}

.pygmentize_wpbTa2  {
  border:3px solid #EEE;
}

.pygmentize_wpbTa2 pre {
  margin-left:20px;
  margin-top:20px;
  margin-bottom:20px;
}

/* When using line numbers, use 100% table width and no cellpadding: */
.pygmentize_wpbTa2table {
  width: 100%;
  border-spacing: 0px;
  border-collapse: collapse;
}


/*
#content table {
    border: 1px solid #E7E7E7;
    margin: 0 -1px 24px 0;
    text-align: left;
    width: 100%;
}
*/

.pygmentize_wpbTa2table td, .pygmentize_wpbTa2table th {
  padding: 0px;
  margin: 0px;
}

/* Add a little buffer so the monotype font doesn't bump directly against the edge: */
.pygmentize_wpbTa2 pre {
  padding: .6ch;
  
}

/* This is more consistent with <p> tags... I didn't like it for my use: */
/*
div .pygmentize_wpbTa2 {
    margin-bottom: 24px; 
}
*/

td.linenos.pygmentize_wpbTa2 {
  width: 1ch;
  padding: .6ch;
  line-height: 1.25em;
}

.pygmentize_wpbTa2 td {
  padding-right: 1px;
}


td.linenos { background-color: #f0f0f0; padding-right: 1px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
pre { line-height: 125%; }
.pygmentize_wpbTa2 .hll { background-color: #ffffcc }
.pygmentize_wpbTa2  { background: #ffffff; }
.pygmentize_wpbTa2 .c { color: #999988; font-style: italic } /* Comment */
.pygmentize_wpbTa2 .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.pygmentize_wpbTa2 .k { color: #000000; font-weight: bold } /* Keyword */
.pygmentize_wpbTa2 .o { color: #000000; font-weight: bold } /* Operator */
.pygmentize_wpbTa2 .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.pygmentize_wpbTa2 .cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */
.pygmentize_wpbTa2 .c1 { color: #999988; font-style: italic } /* Comment.Single */
.pygmentize_wpbTa2 .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.pygmentize_wpbTa2 .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.pygmentize_wpbTa2 .ge { color: #000000; font-style: italic } /* Generic.Emph */
.pygmentize_wpbTa2 .gr { color: #aa0000 } /* Generic.Error */
.pygmentize_wpbTa2 .gh { color: #999999 } /* Generic.Heading */
.pygmentize_wpbTa2 .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.pygmentize_wpbTa2 .go { color: #888888 } /* Generic.Output */
.pygmentize_wpbTa2 .gp { color: #555555 } /* Generic.Prompt */
.pygmentize_wpbTa2 .gs { font-weight: bold } /* Generic.Strong */
.pygmentize_wpbTa2 .gu { color: #aaaaaa } /* Generic.Subheading */
.pygmentize_wpbTa2 .gt { color: #aa0000 } /* Generic.Traceback */
.pygmentize_wpbTa2 .kc { color: #000000; font-weight: bold } /* Keyword.Constant */
.pygmentize_wpbTa2 .kd { color: #000000; font-weight: bold } /* Keyword.Declaration */
.pygmentize_wpbTa2 .kn { color: #000000; font-weight: bold } /* Keyword.Namespace */
.pygmentize_wpbTa2 .kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */
.pygmentize_wpbTa2 .kr { color: #000000; font-weight: bold } /* Keyword.Reserved */
.pygmentize_wpbTa2 .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.pygmentize_wpbTa2 .m { color: #009999 } /* Literal.Number */
.pygmentize_wpbTa2 .s { color: #d01040 } /* Literal.String */
.pygmentize_wpbTa2 .na { color: #008080 } /* Name.Attribute */
.pygmentize_wpbTa2 .nb { color: #0086B3 } /* Name.Builtin */
.pygmentize_wpbTa2 .nc { color: #445588; font-weight: bold } /* Name.Class */
.pygmentize_wpbTa2 .no { color: #008080 } /* Name.Constant */
.pygmentize_wpbTa2 .nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */
.pygmentize_wpbTa2 .ni { color: #800080 } /* Name.Entity */
.pygmentize_wpbTa2 .ne { color: #990000; font-weight: bold } /* Name.Exception */
.pygmentize_wpbTa2 .nf { color: #990000; font-weight: bold } /* Name.Function */
.pygmentize_wpbTa2 .nl { color: #990000; font-weight: bold } /* Name.Label */
.pygmentize_wpbTa2 .nn { color: #555555 } /* Name.Namespace */
.pygmentize_wpbTa2 .nt { color: #000080 } /* Name.Tag */
.pygmentize_wpbTa2 .nv { color: #008080 } /* Name.Variable */
.pygmentize_wpbTa2 .ow { color: #000000; font-weight: bold } /* Operator.Word */
.pygmentize_wpbTa2 .w { color: #bbbbbb } /* Text.Whitespace */
.pygmentize_wpbTa2 .mf { color: #009999 } /* Literal.Number.Float */
.pygmentize_wpbTa2 .mh { color: #009999 } /* Literal.Number.Hex */
.pygmentize_wpbTa2 .mi { color: #009999 } /* Literal.Number.Integer */
.pygmentize_wpbTa2 .mo { color: #009999 } /* Literal.Number.Oct */
.pygmentize_wpbTa2 .sb { color: #d01040 } /* Literal.String.Backtick */
.pygmentize_wpbTa2 .sc { color: #d01040 } /* Literal.String.Char */
.pygmentize_wpbTa2 .sd { color: #d01040 } /* Literal.String.Doc */
.pygmentize_wpbTa2 .s2 { color: #d01040 } /* Literal.String.Double */
.pygmentize_wpbTa2 .se { color: #d01040 } /* Literal.String.Escape */
.pygmentize_wpbTa2 .sh { color: #d01040 } /* Literal.String.Heredoc */
.pygmentize_wpbTa2 .si { color: #d01040 } /* Literal.String.Interpol */
.pygmentize_wpbTa2 .sx { color: #d01040 } /* Literal.String.Other */
.pygmentize_wpbTa2 .sr { color: #009926 } /* Literal.String.Regex */
.pygmentize_wpbTa2 .s1 { color: #d01040 } /* Literal.String.Single */
.pygmentize_wpbTa2 .ss { color: #990073 } /* Literal.String.Symbol */
.pygmentize_wpbTa2 .bp { color: #999999 } /* Name.Builtin.Pseudo */
.pygmentize_wpbTa2 .vc { color: #008080 } /* Name.Variable.Class */
.pygmentize_wpbTa2 .vg { color: #008080 } /* Name.Variable.Global */
.pygmentize_wpbTa2 .vi { color: #008080 } /* Name.Variable.Instance */
.pygmentize_wpbTa2 .il { color: #009999 } /* Literal.Number.Integer.Long */

  </style>




<div class="pygmentize_wpbTa2"><pre>npm install -g coffee-script
</pre></div>

</p>
<p >(El parametro -g es para indicar que es una instalación global que estara disponible para todos los usuarios de tu sistema operativo)</p>
<h2 style="text-align: justify;">Hola Mundo</h2>
<p >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.</p>
<style type="text/css">


/* *************************************************** */
/* WordPress default theme "twenty-ten" compatibility: */
/* FIXME: Is there a way to limit these changes to pygmentize_nhsImm  */
/*        without editing the WordPress theme directly? */
/* *************************************************** */

#content pre {
  /* The background: transparent is needed to work with WordPress:*/
  background: transparent;
  /* Default WordPress style has a big fat <pre> margin-bottom: */
  margin-bottom: 20px;

  /*color: #333333;*/
  font-size: .9em; 
  line-height: 1.25em;
}

#content table {
}

#content table {
	border: 1px solid #e7e7e7;
    margin: 0 0 0 0;
	text-align: left;
	width: 100%;
}
#content tr th,
#content thead th {
	color: #888;
	font-size: 12px;
	font-weight: bold;
	line-height: 18px;
	padding: 0px;
}
#content tr td {
	border: 0px;
	padding: 0px;
	margin: 0px;
    margin-bottom: 0px;
    padding-bottom: 0px;

}

/* *************************************************** */
/* *************************************************** */

/* Standard fixes to the default output: */

/* Set the tab width in "ch" character units: */
.pygmentize_nhsImm .tabspan {
  display: inline-block;
  width: 4ch;
}

.pygmentize_nhsImm  {
  border:3px solid #EEE;
}

.pygmentize_nhsImm pre {
  margin-left:20px;
  margin-top:20px;
  margin-bottom:20px;
}

/* When using line numbers, use 100% table width and no cellpadding: */
.pygmentize_nhsImmtable {
  width: 100%;
  border-spacing: 0px;
  border-collapse: collapse;
}


/*
#content table {
    border: 1px solid #E7E7E7;
    margin: 0 -1px 24px 0;
    text-align: left;
    width: 100%;
}
*/

.pygmentize_nhsImmtable td, .pygmentize_nhsImmtable th {
  padding: 0px;
  margin: 0px;
}

/* Add a little buffer so the monotype font doesn't bump directly against the edge: */
.pygmentize_nhsImm pre {
  padding: .6ch;
  
}

/* This is more consistent with <p> tags... I didn't like it for my use: */
/*
div .pygmentize_nhsImm {
    margin-bottom: 24px; 
}
*/

td.linenos.pygmentize_nhsImm {
  width: 1ch;
  padding: .6ch;
  line-height: 1.25em;
}

.pygmentize_nhsImm td {
  padding-right: 1px;
}


td.linenos { background-color: #f0f0f0; padding-right: 1px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
pre { line-height: 125%; }
.pygmentize_nhsImm .hll { background-color: #ffffcc }
.pygmentize_nhsImm  { background: #ffffff; }
.pygmentize_nhsImm .c { color: #999988; font-style: italic } /* Comment */
.pygmentize_nhsImm .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.pygmentize_nhsImm .k { color: #000000; font-weight: bold } /* Keyword */
.pygmentize_nhsImm .o { color: #000000; font-weight: bold } /* Operator */
.pygmentize_nhsImm .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.pygmentize_nhsImm .cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */
.pygmentize_nhsImm .c1 { color: #999988; font-style: italic } /* Comment.Single */
.pygmentize_nhsImm .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.pygmentize_nhsImm .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.pygmentize_nhsImm .ge { color: #000000; font-style: italic } /* Generic.Emph */
.pygmentize_nhsImm .gr { color: #aa0000 } /* Generic.Error */
.pygmentize_nhsImm .gh { color: #999999 } /* Generic.Heading */
.pygmentize_nhsImm .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.pygmentize_nhsImm .go { color: #888888 } /* Generic.Output */
.pygmentize_nhsImm .gp { color: #555555 } /* Generic.Prompt */
.pygmentize_nhsImm .gs { font-weight: bold } /* Generic.Strong */
.pygmentize_nhsImm .gu { color: #aaaaaa } /* Generic.Subheading */
.pygmentize_nhsImm .gt { color: #aa0000 } /* Generic.Traceback */
.pygmentize_nhsImm .kc { color: #000000; font-weight: bold } /* Keyword.Constant */
.pygmentize_nhsImm .kd { color: #000000; font-weight: bold } /* Keyword.Declaration */
.pygmentize_nhsImm .kn { color: #000000; font-weight: bold } /* Keyword.Namespace */
.pygmentize_nhsImm .kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */
.pygmentize_nhsImm .kr { color: #000000; font-weight: bold } /* Keyword.Reserved */
.pygmentize_nhsImm .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.pygmentize_nhsImm .m { color: #009999 } /* Literal.Number */
.pygmentize_nhsImm .s { color: #d01040 } /* Literal.String */
.pygmentize_nhsImm .na { color: #008080 } /* Name.Attribute */
.pygmentize_nhsImm .nb { color: #0086B3 } /* Name.Builtin */
.pygmentize_nhsImm .nc { color: #445588; font-weight: bold } /* Name.Class */
.pygmentize_nhsImm .no { color: #008080 } /* Name.Constant */
.pygmentize_nhsImm .nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */
.pygmentize_nhsImm .ni { color: #800080 } /* Name.Entity */
.pygmentize_nhsImm .ne { color: #990000; font-weight: bold } /* Name.Exception */
.pygmentize_nhsImm .nf { color: #990000; font-weight: bold } /* Name.Function */
.pygmentize_nhsImm .nl { color: #990000; font-weight: bold } /* Name.Label */
.pygmentize_nhsImm .nn { color: #555555 } /* Name.Namespace */
.pygmentize_nhsImm .nt { color: #000080 } /* Name.Tag */
.pygmentize_nhsImm .nv { color: #008080 } /* Name.Variable */
.pygmentize_nhsImm .ow { color: #000000; font-weight: bold } /* Operator.Word */
.pygmentize_nhsImm .w { color: #bbbbbb } /* Text.Whitespace */
.pygmentize_nhsImm .mf { color: #009999 } /* Literal.Number.Float */
.pygmentize_nhsImm .mh { color: #009999 } /* Literal.Number.Hex */
.pygmentize_nhsImm .mi { color: #009999 } /* Literal.Number.Integer */
.pygmentize_nhsImm .mo { color: #009999 } /* Literal.Number.Oct */
.pygmentize_nhsImm .sb { color: #d01040 } /* Literal.String.Backtick */
.pygmentize_nhsImm .sc { color: #d01040 } /* Literal.String.Char */
.pygmentize_nhsImm .sd { color: #d01040 } /* Literal.String.Doc */
.pygmentize_nhsImm .s2 { color: #d01040 } /* Literal.String.Double */
.pygmentize_nhsImm .se { color: #d01040 } /* Literal.String.Escape */
.pygmentize_nhsImm .sh { color: #d01040 } /* Literal.String.Heredoc */
.pygmentize_nhsImm .si { color: #d01040 } /* Literal.String.Interpol */
.pygmentize_nhsImm .sx { color: #d01040 } /* Literal.String.Other */
.pygmentize_nhsImm .sr { color: #009926 } /* Literal.String.Regex */
.pygmentize_nhsImm .s1 { color: #d01040 } /* Literal.String.Single */
.pygmentize_nhsImm .ss { color: #990073 } /* Literal.String.Symbol */
.pygmentize_nhsImm .bp { color: #999999 } /* Name.Builtin.Pseudo */
.pygmentize_nhsImm .vc { color: #008080 } /* Name.Variable.Class */
.pygmentize_nhsImm .vg { color: #008080 } /* Name.Variable.Global */
.pygmentize_nhsImm .vi { color: #008080 } /* Name.Variable.Instance */
.pygmentize_nhsImm .il { color: #009999 } /* Literal.Number.Integer.Long */

  </style>




<div class="pygmentize_nhsImm"><pre><span class="nv">square = </span><span class="nf">(x) -></span> <span class="nx">x</span> <span class="o">*</span> <span class="nx">x</span>
</pre></div>


<p >Guarda tu archivo como hola.coffee (Si, .coffee es la extensión de los script CoffeeScript)</p>
<p >y luego ejecuta</p>
<style type="text/css">


/* *************************************************** */
/* WordPress default theme "twenty-ten" compatibility: */
/* FIXME: Is there a way to limit these changes to pygmentize_EV7HSG  */
/*        without editing the WordPress theme directly? */
/* *************************************************** */

#content pre {
  /* The background: transparent is needed to work with WordPress:*/
  background: transparent;
  /* Default WordPress style has a big fat <pre> margin-bottom: */
  margin-bottom: 20px;

  /*color: #333333;*/
  font-size: .9em; 
  line-height: 1.25em;
}

#content table {
}

#content table {
	border: 1px solid #e7e7e7;
    margin: 0 0 0 0;
	text-align: left;
	width: 100%;
}
#content tr th,
#content thead th {
	color: #888;
	font-size: 12px;
	font-weight: bold;
	line-height: 18px;
	padding: 0px;
}
#content tr td {
	border: 0px;
	padding: 0px;
	margin: 0px;
    margin-bottom: 0px;
    padding-bottom: 0px;

}

/* *************************************************** */
/* *************************************************** */

/* Standard fixes to the default output: */

/* Set the tab width in "ch" character units: */
.pygmentize_EV7HSG .tabspan {
  display: inline-block;
  width: 4ch;
}

.pygmentize_EV7HSG  {
  border:3px solid #EEE;
}

.pygmentize_EV7HSG pre {
  margin-left:20px;
  margin-top:20px;
  margin-bottom:20px;
}

/* When using line numbers, use 100% table width and no cellpadding: */
.pygmentize_EV7HSGtable {
  width: 100%;
  border-spacing: 0px;
  border-collapse: collapse;
}


/*
#content table {
    border: 1px solid #E7E7E7;
    margin: 0 -1px 24px 0;
    text-align: left;
    width: 100%;
}
*/

.pygmentize_EV7HSGtable td, .pygmentize_EV7HSGtable th {
  padding: 0px;
  margin: 0px;
}

/* Add a little buffer so the monotype font doesn't bump directly against the edge: */
.pygmentize_EV7HSG pre {
  padding: .6ch;
  
}

/* This is more consistent with <p> tags... I didn't like it for my use: */
/*
div .pygmentize_EV7HSG {
    margin-bottom: 24px; 
}
*/

td.linenos.pygmentize_EV7HSG {
  width: 1ch;
  padding: .6ch;
  line-height: 1.25em;
}

.pygmentize_EV7HSG td {
  padding-right: 1px;
}


td.linenos { background-color: #f0f0f0; padding-right: 1px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
pre { line-height: 125%; }
.pygmentize_EV7HSG .hll { background-color: #ffffcc }
.pygmentize_EV7HSG  { background: #ffffff; }
.pygmentize_EV7HSG .c { color: #999988; font-style: italic } /* Comment */
.pygmentize_EV7HSG .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.pygmentize_EV7HSG .k { color: #000000; font-weight: bold } /* Keyword */
.pygmentize_EV7HSG .o { color: #000000; font-weight: bold } /* Operator */
.pygmentize_EV7HSG .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.pygmentize_EV7HSG .cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */
.pygmentize_EV7HSG .c1 { color: #999988; font-style: italic } /* Comment.Single */
.pygmentize_EV7HSG .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.pygmentize_EV7HSG .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.pygmentize_EV7HSG .ge { color: #000000; font-style: italic } /* Generic.Emph */
.pygmentize_EV7HSG .gr { color: #aa0000 } /* Generic.Error */
.pygmentize_EV7HSG .gh { color: #999999 } /* Generic.Heading */
.pygmentize_EV7HSG .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.pygmentize_EV7HSG .go { color: #888888 } /* Generic.Output */
.pygmentize_EV7HSG .gp { color: #555555 } /* Generic.Prompt */
.pygmentize_EV7HSG .gs { font-weight: bold } /* Generic.Strong */
.pygmentize_EV7HSG .gu { color: #aaaaaa } /* Generic.Subheading */
.pygmentize_EV7HSG .gt { color: #aa0000 } /* Generic.Traceback */
.pygmentize_EV7HSG .kc { color: #000000; font-weight: bold } /* Keyword.Constant */
.pygmentize_EV7HSG .kd { color: #000000; font-weight: bold } /* Keyword.Declaration */
.pygmentize_EV7HSG .kn { color: #000000; font-weight: bold } /* Keyword.Namespace */
.pygmentize_EV7HSG .kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */
.pygmentize_EV7HSG .kr { color: #000000; font-weight: bold } /* Keyword.Reserved */
.pygmentize_EV7HSG .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.pygmentize_EV7HSG .m { color: #009999 } /* Literal.Number */
.pygmentize_EV7HSG .s { color: #d01040 } /* Literal.String */
.pygmentize_EV7HSG .na { color: #008080 } /* Name.Attribute */
.pygmentize_EV7HSG .nb { color: #0086B3 } /* Name.Builtin */
.pygmentize_EV7HSG .nc { color: #445588; font-weight: bold } /* Name.Class */
.pygmentize_EV7HSG .no { color: #008080 } /* Name.Constant */
.pygmentize_EV7HSG .nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */
.pygmentize_EV7HSG .ni { color: #800080 } /* Name.Entity */
.pygmentize_EV7HSG .ne { color: #990000; font-weight: bold } /* Name.Exception */
.pygmentize_EV7HSG .nf { color: #990000; font-weight: bold } /* Name.Function */
.pygmentize_EV7HSG .nl { color: #990000; font-weight: bold } /* Name.Label */
.pygmentize_EV7HSG .nn { color: #555555 } /* Name.Namespace */
.pygmentize_EV7HSG .nt { color: #000080 } /* Name.Tag */
.pygmentize_EV7HSG .nv { color: #008080 } /* Name.Variable */
.pygmentize_EV7HSG .ow { color: #000000; font-weight: bold } /* Operator.Word */
.pygmentize_EV7HSG .w { color: #bbbbbb } /* Text.Whitespace */
.pygmentize_EV7HSG .mf { color: #009999 } /* Literal.Number.Float */
.pygmentize_EV7HSG .mh { color: #009999 } /* Literal.Number.Hex */
.pygmentize_EV7HSG .mi { color: #009999 } /* Literal.Number.Integer */
.pygmentize_EV7HSG .mo { color: #009999 } /* Literal.Number.Oct */
.pygmentize_EV7HSG .sb { color: #d01040 } /* Literal.String.Backtick */
.pygmentize_EV7HSG .sc { color: #d01040 } /* Literal.String.Char */
.pygmentize_EV7HSG .sd { color: #d01040 } /* Literal.String.Doc */
.pygmentize_EV7HSG .s2 { color: #d01040 } /* Literal.String.Double */
.pygmentize_EV7HSG .se { color: #d01040 } /* Literal.String.Escape */
.pygmentize_EV7HSG .sh { color: #d01040 } /* Literal.String.Heredoc */
.pygmentize_EV7HSG .si { color: #d01040 } /* Literal.String.Interpol */
.pygmentize_EV7HSG .sx { color: #d01040 } /* Literal.String.Other */
.pygmentize_EV7HSG .sr { color: #009926 } /* Literal.String.Regex */
.pygmentize_EV7HSG .s1 { color: #d01040 } /* Literal.String.Single */
.pygmentize_EV7HSG .ss { color: #990073 } /* Literal.String.Symbol */
.pygmentize_EV7HSG .bp { color: #999999 } /* Name.Builtin.Pseudo */
.pygmentize_EV7HSG .vc { color: #008080 } /* Name.Variable.Class */
.pygmentize_EV7HSG .vg { color: #008080 } /* Name.Variable.Global */
.pygmentize_EV7HSG .vi { color: #008080 } /* Name.Variable.Instance */
.pygmentize_EV7HSG .il { color: #009999 } /* Literal.Number.Integer.Long */

  </style>




<div class="pygmentize_EV7HSG"><pre>coffee -c <span class="s1">&#39;hola.coffee&#39;</span>
</pre></div>


<p >Inmediatamente veras un archivo javascript que se genero con el siguiente código</p>
<p ><style type="text/css">


/* *************************************************** */
/* WordPress default theme "twenty-ten" compatibility: */
/* FIXME: Is there a way to limit these changes to pygmentize_iD2SH1  */
/*        without editing the WordPress theme directly? */
/* *************************************************** */

#content pre {
  /* The background: transparent is needed to work with WordPress:*/
  background: transparent;
  /* Default WordPress style has a big fat <pre> margin-bottom: */
  margin-bottom: 20px;

  /*color: #333333;*/
  font-size: .9em; 
  line-height: 1.25em;
}

#content table {
}

#content table {
	border: 1px solid #e7e7e7;
    margin: 0 0 0 0;
	text-align: left;
	width: 100%;
}
#content tr th,
#content thead th {
	color: #888;
	font-size: 12px;
	font-weight: bold;
	line-height: 18px;
	padding: 0px;
}
#content tr td {
	border: 0px;
	padding: 0px;
	margin: 0px;
    margin-bottom: 0px;
    padding-bottom: 0px;

}

/* *************************************************** */
/* *************************************************** */

/* Standard fixes to the default output: */

/* Set the tab width in "ch" character units: */
.pygmentize_iD2SH1 .tabspan {
  display: inline-block;
  width: 4ch;
}

.pygmentize_iD2SH1  {
  border:3px solid #EEE;
}

.pygmentize_iD2SH1 pre {
  margin-left:20px;
  margin-top:20px;
  margin-bottom:20px;
}

/* When using line numbers, use 100% table width and no cellpadding: */
.pygmentize_iD2SH1table {
  width: 100%;
  border-spacing: 0px;
  border-collapse: collapse;
}


/*
#content table {
    border: 1px solid #E7E7E7;
    margin: 0 -1px 24px 0;
    text-align: left;
    width: 100%;
}
*/

.pygmentize_iD2SH1table td, .pygmentize_iD2SH1table th {
  padding: 0px;
  margin: 0px;
}

/* Add a little buffer so the monotype font doesn't bump directly against the edge: */
.pygmentize_iD2SH1 pre {
  padding: .6ch;
  
}

/* This is more consistent with <p> tags... I didn't like it for my use: */
/*
div .pygmentize_iD2SH1 {
    margin-bottom: 24px; 
}
*/

td.linenos.pygmentize_iD2SH1 {
  width: 1ch;
  padding: .6ch;
  line-height: 1.25em;
}

.pygmentize_iD2SH1 td {
  padding-right: 1px;
}


td.linenos { background-color: #f0f0f0; padding-right: 1px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
pre { line-height: 125%; }
.pygmentize_iD2SH1 .hll { background-color: #ffffcc }
.pygmentize_iD2SH1  { background: #ffffff; }
.pygmentize_iD2SH1 .c { color: #999988; font-style: italic } /* Comment */
.pygmentize_iD2SH1 .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.pygmentize_iD2SH1 .k { color: #000000; font-weight: bold } /* Keyword */
.pygmentize_iD2SH1 .o { color: #000000; font-weight: bold } /* Operator */
.pygmentize_iD2SH1 .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.pygmentize_iD2SH1 .cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */
.pygmentize_iD2SH1 .c1 { color: #999988; font-style: italic } /* Comment.Single */
.pygmentize_iD2SH1 .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.pygmentize_iD2SH1 .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.pygmentize_iD2SH1 .ge { color: #000000; font-style: italic } /* Generic.Emph */
.pygmentize_iD2SH1 .gr { color: #aa0000 } /* Generic.Error */
.pygmentize_iD2SH1 .gh { color: #999999 } /* Generic.Heading */
.pygmentize_iD2SH1 .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.pygmentize_iD2SH1 .go { color: #888888 } /* Generic.Output */
.pygmentize_iD2SH1 .gp { color: #555555 } /* Generic.Prompt */
.pygmentize_iD2SH1 .gs { font-weight: bold } /* Generic.Strong */
.pygmentize_iD2SH1 .gu { color: #aaaaaa } /* Generic.Subheading */
.pygmentize_iD2SH1 .gt { color: #aa0000 } /* Generic.Traceback */
.pygmentize_iD2SH1 .kc { color: #000000; font-weight: bold } /* Keyword.Constant */
.pygmentize_iD2SH1 .kd { color: #000000; font-weight: bold } /* Keyword.Declaration */
.pygmentize_iD2SH1 .kn { color: #000000; font-weight: bold } /* Keyword.Namespace */
.pygmentize_iD2SH1 .kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */
.pygmentize_iD2SH1 .kr { color: #000000; font-weight: bold } /* Keyword.Reserved */
.pygmentize_iD2SH1 .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.pygmentize_iD2SH1 .m { color: #009999 } /* Literal.Number */
.pygmentize_iD2SH1 .s { color: #d01040 } /* Literal.String */
.pygmentize_iD2SH1 .na { color: #008080 } /* Name.Attribute */
.pygmentize_iD2SH1 .nb { color: #0086B3 } /* Name.Builtin */
.pygmentize_iD2SH1 .nc { color: #445588; font-weight: bold } /* Name.Class */
.pygmentize_iD2SH1 .no { color: #008080 } /* Name.Constant */
.pygmentize_iD2SH1 .nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */
.pygmentize_iD2SH1 .ni { color: #800080 } /* Name.Entity */
.pygmentize_iD2SH1 .ne { color: #990000; font-weight: bold } /* Name.Exception */
.pygmentize_iD2SH1 .nf { color: #990000; font-weight: bold } /* Name.Function */
.pygmentize_iD2SH1 .nl { color: #990000; font-weight: bold } /* Name.Label */
.pygmentize_iD2SH1 .nn { color: #555555 } /* Name.Namespace */
.pygmentize_iD2SH1 .nt { color: #000080 } /* Name.Tag */
.pygmentize_iD2SH1 .nv { color: #008080 } /* Name.Variable */
.pygmentize_iD2SH1 .ow { color: #000000; font-weight: bold } /* Operator.Word */
.pygmentize_iD2SH1 .w { color: #bbbbbb } /* Text.Whitespace */
.pygmentize_iD2SH1 .mf { color: #009999 } /* Literal.Number.Float */
.pygmentize_iD2SH1 .mh { color: #009999 } /* Literal.Number.Hex */
.pygmentize_iD2SH1 .mi { color: #009999 } /* Literal.Number.Integer */
.pygmentize_iD2SH1 .mo { color: #009999 } /* Literal.Number.Oct */
.pygmentize_iD2SH1 .sb { color: #d01040 } /* Literal.String.Backtick */
.pygmentize_iD2SH1 .sc { color: #d01040 } /* Literal.String.Char */
.pygmentize_iD2SH1 .sd { color: #d01040 } /* Literal.String.Doc */
.pygmentize_iD2SH1 .s2 { color: #d01040 } /* Literal.String.Double */
.pygmentize_iD2SH1 .se { color: #d01040 } /* Literal.String.Escape */
.pygmentize_iD2SH1 .sh { color: #d01040 } /* Literal.String.Heredoc */
.pygmentize_iD2SH1 .si { color: #d01040 } /* Literal.String.Interpol */
.pygmentize_iD2SH1 .sx { color: #d01040 } /* Literal.String.Other */
.pygmentize_iD2SH1 .sr { color: #009926 } /* Literal.String.Regex */
.pygmentize_iD2SH1 .s1 { color: #d01040 } /* Literal.String.Single */
.pygmentize_iD2SH1 .ss { color: #990073 } /* Literal.String.Symbol */
.pygmentize_iD2SH1 .bp { color: #999999 } /* Name.Builtin.Pseudo */
.pygmentize_iD2SH1 .vc { color: #008080 } /* Name.Variable.Class */
.pygmentize_iD2SH1 .vg { color: #008080 } /* Name.Variable.Global */
.pygmentize_iD2SH1 .vi { color: #008080 } /* Name.Variable.Instance */
.pygmentize_iD2SH1 .il { color: #009999 } /* Literal.Number.Integer.Long */

  </style>




<div class="pygmentize_iD2SH1"><pre></p>
<span class="nv">square</span> <span class="o">=</span> <span class="k">function</span><span class="o">(</span>x<span class="o">)</span> <span class="o">{</span>
<span class="k">return </span>x * x;
<span class="o">}</span>;
</pre></div>

</p>
<p >y ya tienes un archivo .js de toda la vida que puedes usar sin problema en tus aplicaciones web.</p>
<p >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</p>
<style type="text/css">


/* *************************************************** */
/* WordPress default theme "twenty-ten" compatibility: */
/* FIXME: Is there a way to limit these changes to pygmentize_Sn5jRm  */
/*        without editing the WordPress theme directly? */
/* *************************************************** */

#content pre {
  /* The background: transparent is needed to work with WordPress:*/
  background: transparent;
  /* Default WordPress style has a big fat <pre> margin-bottom: */
  margin-bottom: 20px;

  /*color: #333333;*/
  font-size: .9em; 
  line-height: 1.25em;
}

#content table {
}

#content table {
	border: 1px solid #e7e7e7;
    margin: 0 0 0 0;
	text-align: left;
	width: 100%;
}
#content tr th,
#content thead th {
	color: #888;
	font-size: 12px;
	font-weight: bold;
	line-height: 18px;
	padding: 0px;
}
#content tr td {
	border: 0px;
	padding: 0px;
	margin: 0px;
    margin-bottom: 0px;
    padding-bottom: 0px;

}

/* *************************************************** */
/* *************************************************** */

/* Standard fixes to the default output: */

/* Set the tab width in "ch" character units: */
.pygmentize_Sn5jRm .tabspan {
  display: inline-block;
  width: 4ch;
}

.pygmentize_Sn5jRm  {
  border:3px solid #EEE;
}

.pygmentize_Sn5jRm pre {
  margin-left:20px;
  margin-top:20px;
  margin-bottom:20px;
}

/* When using line numbers, use 100% table width and no cellpadding: */
.pygmentize_Sn5jRmtable {
  width: 100%;
  border-spacing: 0px;
  border-collapse: collapse;
}


/*
#content table {
    border: 1px solid #E7E7E7;
    margin: 0 -1px 24px 0;
    text-align: left;
    width: 100%;
}
*/

.pygmentize_Sn5jRmtable td, .pygmentize_Sn5jRmtable th {
  padding: 0px;
  margin: 0px;
}

/* Add a little buffer so the monotype font doesn't bump directly against the edge: */
.pygmentize_Sn5jRm pre {
  padding: .6ch;
  
}

/* This is more consistent with <p> tags... I didn't like it for my use: */
/*
div .pygmentize_Sn5jRm {
    margin-bottom: 24px; 
}
*/

td.linenos.pygmentize_Sn5jRm {
  width: 1ch;
  padding: .6ch;
  line-height: 1.25em;
}

.pygmentize_Sn5jRm td {
  padding-right: 1px;
}


td.linenos { background-color: #f0f0f0; padding-right: 1px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
pre { line-height: 125%; }
.pygmentize_Sn5jRm .hll { background-color: #ffffcc }
.pygmentize_Sn5jRm  { background: #ffffff; }
.pygmentize_Sn5jRm .c { color: #999988; font-style: italic } /* Comment */
.pygmentize_Sn5jRm .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.pygmentize_Sn5jRm .k { color: #000000; font-weight: bold } /* Keyword */
.pygmentize_Sn5jRm .o { color: #000000; font-weight: bold } /* Operator */
.pygmentize_Sn5jRm .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.pygmentize_Sn5jRm .cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */
.pygmentize_Sn5jRm .c1 { color: #999988; font-style: italic } /* Comment.Single */
.pygmentize_Sn5jRm .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.pygmentize_Sn5jRm .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.pygmentize_Sn5jRm .ge { color: #000000; font-style: italic } /* Generic.Emph */
.pygmentize_Sn5jRm .gr { color: #aa0000 } /* Generic.Error */
.pygmentize_Sn5jRm .gh { color: #999999 } /* Generic.Heading */
.pygmentize_Sn5jRm .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.pygmentize_Sn5jRm .go { color: #888888 } /* Generic.Output */
.pygmentize_Sn5jRm .gp { color: #555555 } /* Generic.Prompt */
.pygmentize_Sn5jRm .gs { font-weight: bold } /* Generic.Strong */
.pygmentize_Sn5jRm .gu { color: #aaaaaa } /* Generic.Subheading */
.pygmentize_Sn5jRm .gt { color: #aa0000 } /* Generic.Traceback */
.pygmentize_Sn5jRm .kc { color: #000000; font-weight: bold } /* Keyword.Constant */
.pygmentize_Sn5jRm .kd { color: #000000; font-weight: bold } /* Keyword.Declaration */
.pygmentize_Sn5jRm .kn { color: #000000; font-weight: bold } /* Keyword.Namespace */
.pygmentize_Sn5jRm .kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */
.pygmentize_Sn5jRm .kr { color: #000000; font-weight: bold } /* Keyword.Reserved */
.pygmentize_Sn5jRm .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.pygmentize_Sn5jRm .m { color: #009999 } /* Literal.Number */
.pygmentize_Sn5jRm .s { color: #d01040 } /* Literal.String */
.pygmentize_Sn5jRm .na { color: #008080 } /* Name.Attribute */
.pygmentize_Sn5jRm .nb { color: #0086B3 } /* Name.Builtin */
.pygmentize_Sn5jRm .nc { color: #445588; font-weight: bold } /* Name.Class */
.pygmentize_Sn5jRm .no { color: #008080 } /* Name.Constant */
.pygmentize_Sn5jRm .nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */
.pygmentize_Sn5jRm .ni { color: #800080 } /* Name.Entity */
.pygmentize_Sn5jRm .ne { color: #990000; font-weight: bold } /* Name.Exception */
.pygmentize_Sn5jRm .nf { color: #990000; font-weight: bold } /* Name.Function */
.pygmentize_Sn5jRm .nl { color: #990000; font-weight: bold } /* Name.Label */
.pygmentize_Sn5jRm .nn { color: #555555 } /* Name.Namespace */
.pygmentize_Sn5jRm .nt { color: #000080 } /* Name.Tag */
.pygmentize_Sn5jRm .nv { color: #008080 } /* Name.Variable */
.pygmentize_Sn5jRm .ow { color: #000000; font-weight: bold } /* Operator.Word */
.pygmentize_Sn5jRm .w { color: #bbbbbb } /* Text.Whitespace */
.pygmentize_Sn5jRm .mf { color: #009999 } /* Literal.Number.Float */
.pygmentize_Sn5jRm .mh { color: #009999 } /* Literal.Number.Hex */
.pygmentize_Sn5jRm .mi { color: #009999 } /* Literal.Number.Integer */
.pygmentize_Sn5jRm .mo { color: #009999 } /* Literal.Number.Oct */
.pygmentize_Sn5jRm .sb { color: #d01040 } /* Literal.String.Backtick */
.pygmentize_Sn5jRm .sc { color: #d01040 } /* Literal.String.Char */
.pygmentize_Sn5jRm .sd { color: #d01040 } /* Literal.String.Doc */
.pygmentize_Sn5jRm .s2 { color: #d01040 } /* Literal.String.Double */
.pygmentize_Sn5jRm .se { color: #d01040 } /* Literal.String.Escape */
.pygmentize_Sn5jRm .sh { color: #d01040 } /* Literal.String.Heredoc */
.pygmentize_Sn5jRm .si { color: #d01040 } /* Literal.String.Interpol */
.pygmentize_Sn5jRm .sx { color: #d01040 } /* Literal.String.Other */
.pygmentize_Sn5jRm .sr { color: #009926 } /* Literal.String.Regex */
.pygmentize_Sn5jRm .s1 { color: #d01040 } /* Literal.String.Single */
.pygmentize_Sn5jRm .ss { color: #990073 } /* Literal.String.Symbol */
.pygmentize_Sn5jRm .bp { color: #999999 } /* Name.Builtin.Pseudo */
.pygmentize_Sn5jRm .vc { color: #008080 } /* Name.Variable.Class */
.pygmentize_Sn5jRm .vg { color: #008080 } /* Name.Variable.Global */
.pygmentize_Sn5jRm .vi { color: #008080 } /* Name.Variable.Instance */
.pygmentize_Sn5jRm .il { color: #009999 } /* Literal.Number.Integer.Long */

  </style>




<div class="pygmentize_Sn5jRm"><pre>coffee --watch --compile hola.coffee
</pre></div>


<p >Y ahora cada vez que modifiques tu programa Coffeescript, este auto-mágicamente generara el compilado.</p>
<h2 style="text-align: justify;">Un ejemplo practico</h2>
<p >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?? <img src='http://escueladecodigo.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p >(Que hace el bookmarklet?&#8230;elimina el teclado virtual de <a href="https://www.pcbac.com/PotalaPersonal/login.do" >la siguiente pagina</a> 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 <img src='http://escueladecodigo.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  )</p>
<p >El código original lo puedes encontrar <span ><span >aquí</span></span></p>
<div class="twocol-one">
<style type="text/css">


/* *************************************************** */
/* WordPress default theme "twenty-ten" compatibility: */
/* FIXME: Is there a way to limit these changes to pygmentize_VePFiI  */
/*        without editing the WordPress theme directly? */
/* *************************************************** */

#content pre {
  /* The background: transparent is needed to work with WordPress:*/
  background: transparent;
  /* Default WordPress style has a big fat <pre> margin-bottom: */
  margin-bottom: 20px;

  /*color: #333333;*/
  font-size: .9em; 
  line-height: 1.25em;
}

#content table {
}

#content table {
	border: 1px solid #e7e7e7;
    margin: 0 0 0 0;
	text-align: left;
	width: 100%;
}
#content tr th,
#content thead th {
	color: #888;
	font-size: 12px;
	font-weight: bold;
	line-height: 18px;
	padding: 0px;
}
#content tr td {
	border: 0px;
	padding: 0px;
	margin: 0px;
    margin-bottom: 0px;
    padding-bottom: 0px;

}

/* *************************************************** */
/* *************************************************** */

/* Standard fixes to the default output: */

/* Set the tab width in "ch" character units: */
.pygmentize_VePFiI .tabspan {
  display: inline-block;
  width: 4ch;
}

.pygmentize_VePFiI  {
  border:3px solid #EEE;
}

.pygmentize_VePFiI pre {
  margin-left:20px;
  margin-top:20px;
  margin-bottom:20px;
}

/* When using line numbers, use 100% table width and no cellpadding: */
.pygmentize_VePFiItable {
  width: 100%;
  border-spacing: 0px;
  border-collapse: collapse;
}


/*
#content table {
    border: 1px solid #E7E7E7;
    margin: 0 -1px 24px 0;
    text-align: left;
    width: 100%;
}
*/

.pygmentize_VePFiItable td, .pygmentize_VePFiItable th {
  padding: 0px;
  margin: 0px;
}

/* Add a little buffer so the monotype font doesn't bump directly against the edge: */
.pygmentize_VePFiI pre {
  padding: .6ch;
  
}

/* This is more consistent with <p> tags... I didn't like it for my use: */
/*
div .pygmentize_VePFiI {
    margin-bottom: 24px; 
}
*/

td.linenos.pygmentize_VePFiI {
  width: 1ch;
  padding: .6ch;
  line-height: 1.25em;
}

.pygmentize_VePFiI td {
  padding-right: 1px;
}


td.linenos { background-color: #f0f0f0; padding-right: 1px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
pre { line-height: 125%; }
.pygmentize_VePFiI .hll { background-color: #ffffcc }
.pygmentize_VePFiI  { background: #ffffff; }
.pygmentize_VePFiI .c { color: #999988; font-style: italic } /* Comment */
.pygmentize_VePFiI .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.pygmentize_VePFiI .k { color: #000000; font-weight: bold } /* Keyword */
.pygmentize_VePFiI .o { color: #000000; font-weight: bold } /* Operator */
.pygmentize_VePFiI .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.pygmentize_VePFiI .cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */
.pygmentize_VePFiI .c1 { color: #999988; font-style: italic } /* Comment.Single */
.pygmentize_VePFiI .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.pygmentize_VePFiI .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.pygmentize_VePFiI .ge { color: #000000; font-style: italic } /* Generic.Emph */
.pygmentize_VePFiI .gr { color: #aa0000 } /* Generic.Error */
.pygmentize_VePFiI .gh { color: #999999 } /* Generic.Heading */
.pygmentize_VePFiI .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.pygmentize_VePFiI .go { color: #888888 } /* Generic.Output */
.pygmentize_VePFiI .gp { color: #555555 } /* Generic.Prompt */
.pygmentize_VePFiI .gs { font-weight: bold } /* Generic.Strong */
.pygmentize_VePFiI .gu { color: #aaaaaa } /* Generic.Subheading */
.pygmentize_VePFiI .gt { color: #aa0000 } /* Generic.Traceback */
.pygmentize_VePFiI .kc { color: #000000; font-weight: bold } /* Keyword.Constant */
.pygmentize_VePFiI .kd { color: #000000; font-weight: bold } /* Keyword.Declaration */
.pygmentize_VePFiI .kn { color: #000000; font-weight: bold } /* Keyword.Namespace */
.pygmentize_VePFiI .kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */
.pygmentize_VePFiI .kr { color: #000000; font-weight: bold } /* Keyword.Reserved */
.pygmentize_VePFiI .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.pygmentize_VePFiI .m { color: #009999 } /* Literal.Number */
.pygmentize_VePFiI .s { color: #d01040 } /* Literal.String */
.pygmentize_VePFiI .na { color: #008080 } /* Name.Attribute */
.pygmentize_VePFiI .nb { color: #0086B3 } /* Name.Builtin */
.pygmentize_VePFiI .nc { color: #445588; font-weight: bold } /* Name.Class */
.pygmentize_VePFiI .no { color: #008080 } /* Name.Constant */
.pygmentize_VePFiI .nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */
.pygmentize_VePFiI .ni { color: #800080 } /* Name.Entity */
.pygmentize_VePFiI .ne { color: #990000; font-weight: bold } /* Name.Exception */
.pygmentize_VePFiI .nf { color: #990000; font-weight: bold } /* Name.Function */
.pygmentize_VePFiI .nl { color: #990000; font-weight: bold } /* Name.Label */
.pygmentize_VePFiI .nn { color: #555555 } /* Name.Namespace */
.pygmentize_VePFiI .nt { color: #000080 } /* Name.Tag */
.pygmentize_VePFiI .nv { color: #008080 } /* Name.Variable */
.pygmentize_VePFiI .ow { color: #000000; font-weight: bold } /* Operator.Word */
.pygmentize_VePFiI .w { color: #bbbbbb } /* Text.Whitespace */
.pygmentize_VePFiI .mf { color: #009999 } /* Literal.Number.Float */
.pygmentize_VePFiI .mh { color: #009999 } /* Literal.Number.Hex */
.pygmentize_VePFiI .mi { color: #009999 } /* Literal.Number.Integer */
.pygmentize_VePFiI .mo { color: #009999 } /* Literal.Number.Oct */
.pygmentize_VePFiI .sb { color: #d01040 } /* Literal.String.Backtick */
.pygmentize_VePFiI .sc { color: #d01040 } /* Literal.String.Char */
.pygmentize_VePFiI .sd { color: #d01040 } /* Literal.String.Doc */
.pygmentize_VePFiI .s2 { color: #d01040 } /* Literal.String.Double */
.pygmentize_VePFiI .se { color: #d01040 } /* Literal.String.Escape */
.pygmentize_VePFiI .sh { color: #d01040 } /* Literal.String.Heredoc */
.pygmentize_VePFiI .si { color: #d01040 } /* Literal.String.Interpol */
.pygmentize_VePFiI .sx { color: #d01040 } /* Literal.String.Other */
.pygmentize_VePFiI .sr { color: #009926 } /* Literal.String.Regex */
.pygmentize_VePFiI .s1 { color: #d01040 } /* Literal.String.Single */
.pygmentize_VePFiI .ss { color: #990073 } /* Literal.String.Symbol */
.pygmentize_VePFiI .bp { color: #999999 } /* Name.Builtin.Pseudo */
.pygmentize_VePFiI .vc { color: #008080 } /* Name.Variable.Class */
.pygmentize_VePFiI .vg { color: #008080 } /* Name.Variable.Global */
.pygmentize_VePFiI .vi { color: #008080 } /* Name.Variable.Instance */
.pygmentize_VePFiI .il { color: #009999 } /* Literal.Number.Integer.Long */

  </style>




<div class="pygmentize_VePFiI"><pre><span class="kd">var</span> <span class="nx">ifr</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>

<span class="kd">var</span> <span class="nx">formName</span> <span class="o">=</span> <span class="s1">&#39;loginForm&#39;</span><span class="p">;</span>
</pre></div>


</div>
<div class="twocol-one last">
<style type="text/css">


/* *************************************************** */
/* WordPress default theme "twenty-ten" compatibility: */
/* FIXME: Is there a way to limit these changes to pygmentize_ArbW43  */
/*        without editing the WordPress theme directly? */
/* *************************************************** */

#content pre {
  /* The background: transparent is needed to work with WordPress:*/
  background: transparent;
  /* Default WordPress style has a big fat <pre> margin-bottom: */
  margin-bottom: 20px;

  /*color: #333333;*/
  font-size: .9em; 
  line-height: 1.25em;
}

#content table {
}

#content table {
	border: 1px solid #e7e7e7;
    margin: 0 0 0 0;
	text-align: left;
	width: 100%;
}
#content tr th,
#content thead th {
	color: #888;
	font-size: 12px;
	font-weight: bold;
	line-height: 18px;
	padding: 0px;
}
#content tr td {
	border: 0px;
	padding: 0px;
	margin: 0px;
    margin-bottom: 0px;
    padding-bottom: 0px;

}

/* *************************************************** */
/* *************************************************** */

/* Standard fixes to the default output: */

/* Set the tab width in "ch" character units: */
.pygmentize_ArbW43 .tabspan {
  display: inline-block;
  width: 4ch;
}

.pygmentize_ArbW43  {
  border:3px solid #EEE;
}

.pygmentize_ArbW43 pre {
  margin-left:20px;
  margin-top:20px;
  margin-bottom:20px;
}

/* When using line numbers, use 100% table width and no cellpadding: */
.pygmentize_ArbW43table {
  width: 100%;
  border-spacing: 0px;
  border-collapse: collapse;
}


/*
#content table {
    border: 1px solid #E7E7E7;
    margin: 0 -1px 24px 0;
    text-align: left;
    width: 100%;
}
*/

.pygmentize_ArbW43table td, .pygmentize_ArbW43table th {
  padding: 0px;
  margin: 0px;
}

/* Add a little buffer so the monotype font doesn't bump directly against the edge: */
.pygmentize_ArbW43 pre {
  padding: .6ch;
  
}

/* This is more consistent with <p> tags... I didn't like it for my use: */
/*
div .pygmentize_ArbW43 {
    margin-bottom: 24px; 
}
*/

td.linenos.pygmentize_ArbW43 {
  width: 1ch;
  padding: .6ch;
  line-height: 1.25em;
}

.pygmentize_ArbW43 td {
  padding-right: 1px;
}


td.linenos { background-color: #f0f0f0; padding-right: 1px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
pre { line-height: 125%; }
.pygmentize_ArbW43 .hll { background-color: #ffffcc }
.pygmentize_ArbW43  { background: #ffffff; }
.pygmentize_ArbW43 .c { color: #999988; font-style: italic } /* Comment */
.pygmentize_ArbW43 .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.pygmentize_ArbW43 .k { color: #000000; font-weight: bold } /* Keyword */
.pygmentize_ArbW43 .o { color: #000000; font-weight: bold } /* Operator */
.pygmentize_ArbW43 .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.pygmentize_ArbW43 .cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */
.pygmentize_ArbW43 .c1 { color: #999988; font-style: italic } /* Comment.Single */
.pygmentize_ArbW43 .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.pygmentize_ArbW43 .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.pygmentize_ArbW43 .ge { color: #000000; font-style: italic } /* Generic.Emph */
.pygmentize_ArbW43 .gr { color: #aa0000 } /* Generic.Error */
.pygmentize_ArbW43 .gh { color: #999999 } /* Generic.Heading */
.pygmentize_ArbW43 .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.pygmentize_ArbW43 .go { color: #888888 } /* Generic.Output */
.pygmentize_ArbW43 .gp { color: #555555 } /* Generic.Prompt */
.pygmentize_ArbW43 .gs { font-weight: bold } /* Generic.Strong */
.pygmentize_ArbW43 .gu { color: #aaaaaa } /* Generic.Subheading */
.pygmentize_ArbW43 .gt { color: #aa0000 } /* Generic.Traceback */
.pygmentize_ArbW43 .kc { color: #000000; font-weight: bold } /* Keyword.Constant */
.pygmentize_ArbW43 .kd { color: #000000; font-weight: bold } /* Keyword.Declaration */
.pygmentize_ArbW43 .kn { color: #000000; font-weight: bold } /* Keyword.Namespace */
.pygmentize_ArbW43 .kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */
.pygmentize_ArbW43 .kr { color: #000000; font-weight: bold } /* Keyword.Reserved */
.pygmentize_ArbW43 .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.pygmentize_ArbW43 .m { color: #009999 } /* Literal.Number */
.pygmentize_ArbW43 .s { color: #d01040 } /* Literal.String */
.pygmentize_ArbW43 .na { color: #008080 } /* Name.Attribute */
.pygmentize_ArbW43 .nb { color: #0086B3 } /* Name.Builtin */
.pygmentize_ArbW43 .nc { color: #445588; font-weight: bold } /* Name.Class */
.pygmentize_ArbW43 .no { color: #008080 } /* Name.Constant */
.pygmentize_ArbW43 .nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */
.pygmentize_ArbW43 .ni { color: #800080 } /* Name.Entity */
.pygmentize_ArbW43 .ne { color: #990000; font-weight: bold } /* Name.Exception */
.pygmentize_ArbW43 .nf { color: #990000; font-weight: bold } /* Name.Function */
.pygmentize_ArbW43 .nl { color: #990000; font-weight: bold } /* Name.Label */
.pygmentize_ArbW43 .nn { color: #555555 } /* Name.Namespace */
.pygmentize_ArbW43 .nt { color: #000080 } /* Name.Tag */
.pygmentize_ArbW43 .nv { color: #008080 } /* Name.Variable */
.pygmentize_ArbW43 .ow { color: #000000; font-weight: bold } /* Operator.Word */
.pygmentize_ArbW43 .w { color: #bbbbbb } /* Text.Whitespace */
.pygmentize_ArbW43 .mf { color: #009999 } /* Literal.Number.Float */
.pygmentize_ArbW43 .mh { color: #009999 } /* Literal.Number.Hex */
.pygmentize_ArbW43 .mi { color: #009999 } /* Literal.Number.Integer */
.pygmentize_ArbW43 .mo { color: #009999 } /* Literal.Number.Oct */
.pygmentize_ArbW43 .sb { color: #d01040 } /* Literal.String.Backtick */
.pygmentize_ArbW43 .sc { color: #d01040 } /* Literal.String.Char */
.pygmentize_ArbW43 .sd { color: #d01040 } /* Literal.String.Doc */
.pygmentize_ArbW43 .s2 { color: #d01040 } /* Literal.String.Double */
.pygmentize_ArbW43 .se { color: #d01040 } /* Literal.String.Escape */
.pygmentize_ArbW43 .sh { color: #d01040 } /* Literal.String.Heredoc */
.pygmentize_ArbW43 .si { color: #d01040 } /* Literal.String.Interpol */
.pygmentize_ArbW43 .sx { color: #d01040 } /* Literal.String.Other */
.pygmentize_ArbW43 .sr { color: #009926 } /* Literal.String.Regex */
.pygmentize_ArbW43 .s1 { color: #d01040 } /* Literal.String.Single */
.pygmentize_ArbW43 .ss { color: #990073 } /* Literal.String.Symbol */
.pygmentize_ArbW43 .bp { color: #999999 } /* Name.Builtin.Pseudo */
.pygmentize_ArbW43 .vc { color: #008080 } /* Name.Variable.Class */
.pygmentize_ArbW43 .vg { color: #008080 } /* Name.Variable.Global */
.pygmentize_ArbW43 .vi { color: #008080 } /* Name.Variable.Instance */
.pygmentize_ArbW43 .il { color: #009999 } /* Literal.Number.Integer.Long */

  </style>




<div class="pygmentize_ArbW43"><pre><span class="c1">#Comentarios</span>

<span class="nv">ifr = </span><span class="kc">off</span>

<span class="nv">formName = </span><span class="s1">&#39;loginForm&#39;</span>
</pre></div>


</div>
<h3>Variables</h3>
<p >El script empieza definiendo unas cuantas variables,en CoffeeScript para definir variables no es necesario usar la palabra reservada <code><strong>var </strong></code>y en terminos generales los punto y coma no son requeridos.</p>
<h3 style="text-align: justify;">Comentarios</h3>
<p>Los comentarios no son compilados a javascript y se escriben anteponiendo <code>#</code></p>
<h3 style="text-align: justify;">Booleanos</h3>
<p >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 <code><strong>false </strong></code>con <code><strong>off </strong></code>o <code><strong>no</strong></code>, para <code><strong>true </strong></code>se utilizan <code><strong>yes </strong></code>o <code><strong>on</strong></code>.</p>
<div class="twocol-one">
<style type="text/css">


/* *************************************************** */
/* WordPress default theme "twenty-ten" compatibility: */
/* FIXME: Is there a way to limit these changes to pygmentize_xFpm9p  */
/*        without editing the WordPress theme directly? */
/* *************************************************** */

#content pre {
  /* The background: transparent is needed to work with WordPress:*/
  background: transparent;
  /* Default WordPress style has a big fat <pre> margin-bottom: */
  margin-bottom: 20px;

  /*color: #333333;*/
  font-size: .9em; 
  line-height: 1.25em;
}

#content table {
}

#content table {
	border: 1px solid #e7e7e7;
    margin: 0 0 0 0;
	text-align: left;
	width: 100%;
}
#content tr th,
#content thead th {
	color: #888;
	font-size: 12px;
	font-weight: bold;
	line-height: 18px;
	padding: 0px;
}
#content tr td {
	border: 0px;
	padding: 0px;
	margin: 0px;
    margin-bottom: 0px;
    padding-bottom: 0px;

}

/* *************************************************** */
/* *************************************************** */

/* Standard fixes to the default output: */

/* Set the tab width in "ch" character units: */
.pygmentize_xFpm9p .tabspan {
  display: inline-block;
  width: 4ch;
}

.pygmentize_xFpm9p  {
  border:3px solid #EEE;
}

.pygmentize_xFpm9p pre {
  margin-left:20px;
  margin-top:20px;
  margin-bottom:20px;
}

/* When using line numbers, use 100% table width and no cellpadding: */
.pygmentize_xFpm9ptable {
  width: 100%;
  border-spacing: 0px;
  border-collapse: collapse;
}


/*
#content table {
    border: 1px solid #E7E7E7;
    margin: 0 -1px 24px 0;
    text-align: left;
    width: 100%;
}
*/

.pygmentize_xFpm9ptable td, .pygmentize_xFpm9ptable th {
  padding: 0px;
  margin: 0px;
}

/* Add a little buffer so the monotype font doesn't bump directly against the edge: */
.pygmentize_xFpm9p pre {
  padding: .6ch;
  
}

/* This is more consistent with <p> tags... I didn't like it for my use: */
/*
div .pygmentize_xFpm9p {
    margin-bottom: 24px; 
}
*/

td.linenos.pygmentize_xFpm9p {
  width: 1ch;
  padding: .6ch;
  line-height: 1.25em;
}

.pygmentize_xFpm9p td {
  padding-right: 1px;
}


td.linenos { background-color: #f0f0f0; padding-right: 1px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
pre { line-height: 125%; }
.pygmentize_xFpm9p .hll { background-color: #ffffcc }
.pygmentize_xFpm9p  { background: #ffffff; }
.pygmentize_xFpm9p .c { color: #999988; font-style: italic } /* Comment */
.pygmentize_xFpm9p .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.pygmentize_xFpm9p .k { color: #000000; font-weight: bold } /* Keyword */
.pygmentize_xFpm9p .o { color: #000000; font-weight: bold } /* Operator */
.pygmentize_xFpm9p .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.pygmentize_xFpm9p .cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */
.pygmentize_xFpm9p .c1 { color: #999988; font-style: italic } /* Comment.Single */
.pygmentize_xFpm9p .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.pygmentize_xFpm9p .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.pygmentize_xFpm9p .ge { color: #000000; font-style: italic } /* Generic.Emph */
.pygmentize_xFpm9p .gr { color: #aa0000 } /* Generic.Error */
.pygmentize_xFpm9p .gh { color: #999999 } /* Generic.Heading */
.pygmentize_xFpm9p .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.pygmentize_xFpm9p .go { color: #888888 } /* Generic.Output */
.pygmentize_xFpm9p .gp { color: #555555 } /* Generic.Prompt */
.pygmentize_xFpm9p .gs { font-weight: bold } /* Generic.Strong */
.pygmentize_xFpm9p .gu { color: #aaaaaa } /* Generic.Subheading */
.pygmentize_xFpm9p .gt { color: #aa0000 } /* Generic.Traceback */
.pygmentize_xFpm9p .kc { color: #000000; font-weight: bold } /* Keyword.Constant */
.pygmentize_xFpm9p .kd { color: #000000; font-weight: bold } /* Keyword.Declaration */
.pygmentize_xFpm9p .kn { color: #000000; font-weight: bold } /* Keyword.Namespace */
.pygmentize_xFpm9p .kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */
.pygmentize_xFpm9p .kr { color: #000000; font-weight: bold } /* Keyword.Reserved */
.pygmentize_xFpm9p .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.pygmentize_xFpm9p .m { color: #009999 } /* Literal.Number */
.pygmentize_xFpm9p .s { color: #d01040 } /* Literal.String */
.pygmentize_xFpm9p .na { color: #008080 } /* Name.Attribute */
.pygmentize_xFpm9p .nb { color: #0086B3 } /* Name.Builtin */
.pygmentize_xFpm9p .nc { color: #445588; font-weight: bold } /* Name.Class */
.pygmentize_xFpm9p .no { color: #008080 } /* Name.Constant */
.pygmentize_xFpm9p .nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */
.pygmentize_xFpm9p .ni { color: #800080 } /* Name.Entity */
.pygmentize_xFpm9p .ne { color: #990000; font-weight: bold } /* Name.Exception */
.pygmentize_xFpm9p .nf { color: #990000; font-weight: bold } /* Name.Function */
.pygmentize_xFpm9p .nl { color: #990000; font-weight: bold } /* Name.Label */
.pygmentize_xFpm9p .nn { color: #555555 } /* Name.Namespace */
.pygmentize_xFpm9p .nt { color: #000080 } /* Name.Tag */
.pygmentize_xFpm9p .nv { color: #008080 } /* Name.Variable */
.pygmentize_xFpm9p .ow { color: #000000; font-weight: bold } /* Operator.Word */
.pygmentize_xFpm9p .w { color: #bbbbbb } /* Text.Whitespace */
.pygmentize_xFpm9p .mf { color: #009999 } /* Literal.Number.Float */
.pygmentize_xFpm9p .mh { color: #009999 } /* Literal.Number.Hex */
.pygmentize_xFpm9p .mi { color: #009999 } /* Literal.Number.Integer */
.pygmentize_xFpm9p .mo { color: #009999 } /* Literal.Number.Oct */
.pygmentize_xFpm9p .sb { color: #d01040 } /* Literal.String.Backtick */
.pygmentize_xFpm9p .sc { color: #d01040 } /* Literal.String.Char */
.pygmentize_xFpm9p .sd { color: #d01040 } /* Literal.String.Doc */
.pygmentize_xFpm9p .s2 { color: #d01040 } /* Literal.String.Double */
.pygmentize_xFpm9p .se { color: #d01040 } /* Literal.String.Escape */
.pygmentize_xFpm9p .sh { color: #d01040 } /* Literal.String.Heredoc */
.pygmentize_xFpm9p .si { color: #d01040 } /* Literal.String.Interpol */
.pygmentize_xFpm9p .sx { color: #d01040 } /* Literal.String.Other */
.pygmentize_xFpm9p .sr { color: #009926 } /* Literal.String.Regex */
.pygmentize_xFpm9p .s1 { color: #d01040 } /* Literal.String.Single */
.pygmentize_xFpm9p .ss { color: #990073 } /* Literal.String.Symbol */
.pygmentize_xFpm9p .bp { color: #999999 } /* Name.Builtin.Pseudo */
.pygmentize_xFpm9p .vc { color: #008080 } /* Name.Variable.Class */
.pygmentize_xFpm9p .vg { color: #008080 } /* Name.Variable.Global */
.pygmentize_xFpm9p .vi { color: #008080 } /* Name.Variable.Instance */
.pygmentize_xFpm9p .il { color: #009999 } /* Literal.Number.Integer.Long */

  </style>




<div class="pygmentize_xFpm9p"><pre><span class="kd">var</span> <span class="nx">$</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">idname</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">doc</span> <span class="o">=</span> <span class="nx">ifr</span> <span class="o">?</span> <span class="nb">window</span><span class="p">.</span><span class="nx">frames</span><span class="p">.</span><span class="nx">working</span><span class="p">.</span><span class="nb">document</span> <span class="o">:</span> <span class="nb">document</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">doc</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="nx">idname</span><span class="p">)</span> <span class="o">||</span>
<span class="nx">doc</span><span class="p">.</span><span class="nx">getElementsByName</span><span class="p">(</span><span class="nx">idname</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="o">||</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>


</div>
<div class="twocol-one last">
<p><style type="text/css">


/* *************************************************** */
/* WordPress default theme "twenty-ten" compatibility: */
/* FIXME: Is there a way to limit these changes to pygmentize_QySrwM  */
/*        without editing the WordPress theme directly? */
/* *************************************************** */

#content pre {
  /* The background: transparent is needed to work with WordPress:*/
  background: transparent;
  /* Default WordPress style has a big fat <pre> margin-bottom: */
  margin-bottom: 20px;

  /*color: #333333;*/
  font-size: .9em; 
  line-height: 1.25em;
}

#content table {
}

#content table {
	border: 1px solid #e7e7e7;
    margin: 0 0 0 0;
	text-align: left;
	width: 100%;
}
#content tr th,
#content thead th {
	color: #888;
	font-size: 12px;
	font-weight: bold;
	line-height: 18px;
	padding: 0px;
}
#content tr td {
	border: 0px;
	padding: 0px;
	margin: 0px;
    margin-bottom: 0px;
    padding-bottom: 0px;

}

/* *************************************************** */
/* *************************************************** */

/* Standard fixes to the default output: */

/* Set the tab width in "ch" character units: */
.pygmentize_QySrwM .tabspan {
  display: inline-block;
  width: 4ch;
}

.pygmentize_QySrwM  {
  border:3px solid #EEE;
}

.pygmentize_QySrwM pre {
  margin-left:20px;
  margin-top:20px;
  margin-bottom:20px;
}

/* When using line numbers, use 100% table width and no cellpadding: */
.pygmentize_QySrwMtable {
  width: 100%;
  border-spacing: 0px;
  border-collapse: collapse;
}


/*
#content table {
    border: 1px solid #E7E7E7;
    margin: 0 -1px 24px 0;
    text-align: left;
    width: 100%;
}
*/

.pygmentize_QySrwMtable td, .pygmentize_QySrwMtable th {
  padding: 0px;
  margin: 0px;
}

/* Add a little buffer so the monotype font doesn't bump directly against the edge: */
.pygmentize_QySrwM pre {
  padding: .6ch;
  
}

/* This is more consistent with <p> tags... I didn't like it for my use: */
/*
div .pygmentize_QySrwM {
    margin-bottom: 24px; 
}
*/

td.linenos.pygmentize_QySrwM {
  width: 1ch;
  padding: .6ch;
  line-height: 1.25em;
}

.pygmentize_QySrwM td {
  padding-right: 1px;
}


td.linenos { background-color: #f0f0f0; padding-right: 1px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
pre { line-height: 125%; }
.pygmentize_QySrwM .hll { background-color: #ffffcc }
.pygmentize_QySrwM  { background: #ffffff; }
.pygmentize_QySrwM .c { color: #999988; font-style: italic } /* Comment */
.pygmentize_QySrwM .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.pygmentize_QySrwM .k { color: #000000; font-weight: bold } /* Keyword */
.pygmentize_QySrwM .o { color: #000000; font-weight: bold } /* Operator */
.pygmentize_QySrwM .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.pygmentize_QySrwM .cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */
.pygmentize_QySrwM .c1 { color: #999988; font-style: italic } /* Comment.Single */
.pygmentize_QySrwM .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.pygmentize_QySrwM .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.pygmentize_QySrwM .ge { color: #000000; font-style: italic } /* Generic.Emph */
.pygmentize_QySrwM .gr { color: #aa0000 } /* Generic.Error */
.pygmentize_QySrwM .gh { color: #999999 } /* Generic.Heading */
.pygmentize_QySrwM .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.pygmentize_QySrwM .go { color: #888888 } /* Generic.Output */
.pygmentize_QySrwM .gp { color: #555555 } /* Generic.Prompt */
.pygmentize_QySrwM .gs { font-weight: bold } /* Generic.Strong */
.pygmentize_QySrwM .gu { color: #aaaaaa } /* Generic.Subheading */
.pygmentize_QySrwM .gt { color: #aa0000 } /* Generic.Traceback */
.pygmentize_QySrwM .kc { color: #000000; font-weight: bold } /* Keyword.Constant */
.pygmentize_QySrwM .kd { color: #000000; font-weight: bold } /* Keyword.Declaration */
.pygmentize_QySrwM .kn { color: #000000; font-weight: bold } /* Keyword.Namespace */
.pygmentize_QySrwM .kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */
.pygmentize_QySrwM .kr { color: #000000; font-weight: bold } /* Keyword.Reserved */
.pygmentize_QySrwM .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.pygmentize_QySrwM .m { color: #009999 } /* Literal.Number */
.pygmentize_QySrwM .s { color: #d01040 } /* Literal.String */
.pygmentize_QySrwM .na { color: #008080 } /* Name.Attribute */
.pygmentize_QySrwM .nb { color: #0086B3 } /* Name.Builtin */
.pygmentize_QySrwM .nc { color: #445588; font-weight: bold } /* Name.Class */
.pygmentize_QySrwM .no { color: #008080 } /* Name.Constant */
.pygmentize_QySrwM .nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */
.pygmentize_QySrwM .ni { color: #800080 } /* Name.Entity */
.pygmentize_QySrwM .ne { color: #990000; font-weight: bold } /* Name.Exception */
.pygmentize_QySrwM .nf { color: #990000; font-weight: bold } /* Name.Function */
.pygmentize_QySrwM .nl { color: #990000; font-weight: bold } /* Name.Label */
.pygmentize_QySrwM .nn { color: #555555 } /* Name.Namespace */
.pygmentize_QySrwM .nt { color: #000080 } /* Name.Tag */
.pygmentize_QySrwM .nv { color: #008080 } /* Name.Variable */
.pygmentize_QySrwM .ow { color: #000000; font-weight: bold } /* Operator.Word */
.pygmentize_QySrwM .w { color: #bbbbbb } /* Text.Whitespace */
.pygmentize_QySrwM .mf { color: #009999 } /* Literal.Number.Float */
.pygmentize_QySrwM .mh { color: #009999 } /* Literal.Number.Hex */
.pygmentize_QySrwM .mi { color: #009999 } /* Literal.Number.Integer */
.pygmentize_QySrwM .mo { color: #009999 } /* Literal.Number.Oct */
.pygmentize_QySrwM .sb { color: #d01040 } /* Literal.String.Backtick */
.pygmentize_QySrwM .sc { color: #d01040 } /* Literal.String.Char */
.pygmentize_QySrwM .sd { color: #d01040 } /* Literal.String.Doc */
.pygmentize_QySrwM .s2 { color: #d01040 } /* Literal.String.Double */
.pygmentize_QySrwM .se { color: #d01040 } /* Literal.String.Escape */
.pygmentize_QySrwM .sh { color: #d01040 } /* Literal.String.Heredoc */
.pygmentize_QySrwM .si { color: #d01040 } /* Literal.String.Interpol */
.pygmentize_QySrwM .sx { color: #d01040 } /* Literal.String.Other */
.pygmentize_QySrwM .sr { color: #009926 } /* Literal.String.Regex */
.pygmentize_QySrwM .s1 { color: #d01040 } /* Literal.String.Single */
.pygmentize_QySrwM .ss { color: #990073 } /* Literal.String.Symbol */
.pygmentize_QySrwM .bp { color: #999999 } /* Name.Builtin.Pseudo */
.pygmentize_QySrwM .vc { color: #008080 } /* Name.Variable.Class */
.pygmentize_QySrwM .vg { color: #008080 } /* Name.Variable.Global */
.pygmentize_QySrwM .vi { color: #008080 } /* Name.Variable.Instance */
.pygmentize_QySrwM .il { color: #009999 } /* Literal.Number.Integer.Long */

  </style>




<div class="pygmentize_QySrwM"><pre><span class="nv">$ = </span><span class="nf">(idname) -></span>
<span class="nv">doc = </span><span class="k">if</span> <span class="nx">ifr</span> <span class="k">then</span> <span class="nb">window</span><span class="p">.</span><span class="nx">frames</span><span class="p">.</span><span class="nx">working</span><span class="p">.</span><span class="nb">document</span> <span class="k">else</span> <span class="nb">document</span>
<span class="nx">doc</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="nx">idname</span><span class="p">)</span> <span class="o">or</span>
<span class="nx">doc</span><span class="p">.</span><span class="nx">getElementsByName</span><span class="p">(</span><span class="nx">idname</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="o">or</span> <span class="s1">&#39;&#39;</span>
</pre></div>

<br />
</div>
<h3>Funciones</h3>
<p >Las funciones se definen siguiendo la estructura <code><strong>nombre = (parametros entre parentesis) -> [cuerpo de la funcion] </strong></code>sino existen parametros se omiten los parentesis, la palabra reservada <code><strong>return </strong></code>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 <code><strong>parametro='valor'.</strong></code></p>
<h3 style="text-align: justify;">Sentencias condicionales</h3>
<p>Para definir un <code>if</code> corto <em>(condicion?true:false) </em>se utiliza un lenguaje mas natural <code><strong>if </strong>condicion<strong> then </strong>true<strong> else </strong>false.</code> Es de notar que las llaves y paréntesis tampoco son necesarios.</p>
<h3>Operadores Lógicos</h3>
<p>Los operadores logicos tambien tienen alias, para el caso de <code>||</code> se puede sustituir con <code>or</code></p>
<div class="twocol-one">
<style type="text/css">


/* *************************************************** */
/* WordPress default theme "twenty-ten" compatibility: */
/* FIXME: Is there a way to limit these changes to pygmentize_8U2Wb9  */
/*        without editing the WordPress theme directly? */
/* *************************************************** */

#content pre {
  /* The background: transparent is needed to work with WordPress:*/
  background: transparent;
  /* Default WordPress style has a big fat <pre> margin-bottom: */
  margin-bottom: 20px;

  /*color: #333333;*/
  font-size: .9em; 
  line-height: 1.25em;
}

#content table {
}

#content table {
	border: 1px solid #e7e7e7;
    margin: 0 0 0 0;
	text-align: left;
	width: 100%;
}
#content tr th,
#content thead th {
	color: #888;
	font-size: 12px;
	font-weight: bold;
	line-height: 18px;
	padding: 0px;
}
#content tr td {
	border: 0px;
	padding: 0px;
	margin: 0px;
    margin-bottom: 0px;
    padding-bottom: 0px;

}

/* *************************************************** */
/* *************************************************** */

/* Standard fixes to the default output: */

/* Set the tab width in "ch" character units: */
.pygmentize_8U2Wb9 .tabspan {
  display: inline-block;
  width: 4ch;
}

.pygmentize_8U2Wb9  {
  border:3px solid #EEE;
}

.pygmentize_8U2Wb9 pre {
  margin-left:20px;
  margin-top:20px;
  margin-bottom:20px;
}

/* When using line numbers, use 100% table width and no cellpadding: */
.pygmentize_8U2Wb9table {
  width: 100%;
  border-spacing: 0px;
  border-collapse: collapse;
}


/*
#content table {
    border: 1px solid #E7E7E7;
    margin: 0 -1px 24px 0;
    text-align: left;
    width: 100%;
}
*/

.pygmentize_8U2Wb9table td, .pygmentize_8U2Wb9table th {
  padding: 0px;
  margin: 0px;
}

/* Add a little buffer so the monotype font doesn't bump directly against the edge: */
.pygmentize_8U2Wb9 pre {
  padding: .6ch;
  
}

/* This is more consistent with <p> tags... I didn't like it for my use: */
/*
div .pygmentize_8U2Wb9 {
    margin-bottom: 24px; 
}
*/

td.linenos.pygmentize_8U2Wb9 {
  width: 1ch;
  padding: .6ch;
  line-height: 1.25em;
}

.pygmentize_8U2Wb9 td {
  padding-right: 1px;
}


td.linenos { background-color: #f0f0f0; padding-right: 1px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
pre { line-height: 125%; }
.pygmentize_8U2Wb9 .hll { background-color: #ffffcc }
.pygmentize_8U2Wb9  { background: #ffffff; }
.pygmentize_8U2Wb9 .c { color: #999988; font-style: italic } /* Comment */
.pygmentize_8U2Wb9 .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.pygmentize_8U2Wb9 .k { color: #000000; font-weight: bold } /* Keyword */
.pygmentize_8U2Wb9 .o { color: #000000; font-weight: bold } /* Operator */
.pygmentize_8U2Wb9 .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.pygmentize_8U2Wb9 .cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */
.pygmentize_8U2Wb9 .c1 { color: #999988; font-style: italic } /* Comment.Single */
.pygmentize_8U2Wb9 .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.pygmentize_8U2Wb9 .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.pygmentize_8U2Wb9 .ge { color: #000000; font-style: italic } /* Generic.Emph */
.pygmentize_8U2Wb9 .gr { color: #aa0000 } /* Generic.Error */
.pygmentize_8U2Wb9 .gh { color: #999999 } /* Generic.Heading */
.pygmentize_8U2Wb9 .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.pygmentize_8U2Wb9 .go { color: #888888 } /* Generic.Output */
.pygmentize_8U2Wb9 .gp { color: #555555 } /* Generic.Prompt */
.pygmentize_8U2Wb9 .gs { font-weight: bold } /* Generic.Strong */
.pygmentize_8U2Wb9 .gu { color: #aaaaaa } /* Generic.Subheading */
.pygmentize_8U2Wb9 .gt { color: #aa0000 } /* Generic.Traceback */
.pygmentize_8U2Wb9 .kc { color: #000000; font-weight: bold } /* Keyword.Constant */
.pygmentize_8U2Wb9 .kd { color: #000000; font-weight: bold } /* Keyword.Declaration */
.pygmentize_8U2Wb9 .kn { color: #000000; font-weight: bold } /* Keyword.Namespace */
.pygmentize_8U2Wb9 .kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */
.pygmentize_8U2Wb9 .kr { color: #000000; font-weight: bold } /* Keyword.Reserved */
.pygmentize_8U2Wb9 .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.pygmentize_8U2Wb9 .m { color: #009999 } /* Literal.Number */
.pygmentize_8U2Wb9 .s { color: #d01040 } /* Literal.String */
.pygmentize_8U2Wb9 .na { color: #008080 } /* Name.Attribute */
.pygmentize_8U2Wb9 .nb { color: #0086B3 } /* Name.Builtin */
.pygmentize_8U2Wb9 .nc { color: #445588; font-weight: bold } /* Name.Class */
.pygmentize_8U2Wb9 .no { color: #008080 } /* Name.Constant */
.pygmentize_8U2Wb9 .nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */
.pygmentize_8U2Wb9 .ni { color: #800080 } /* Name.Entity */
.pygmentize_8U2Wb9 .ne { color: #990000; font-weight: bold } /* Name.Exception */
.pygmentize_8U2Wb9 .nf { color: #990000; font-weight: bold } /* Name.Function */
.pygmentize_8U2Wb9 .nl { color: #990000; font-weight: bold } /* Name.Label */
.pygmentize_8U2Wb9 .nn { color: #555555 } /* Name.Namespace */
.pygmentize_8U2Wb9 .nt { color: #000080 } /* Name.Tag */
.pygmentize_8U2Wb9 .nv { color: #008080 } /* Name.Variable */
.pygmentize_8U2Wb9 .ow { color: #000000; font-weight: bold } /* Operator.Word */
.pygmentize_8U2Wb9 .w { color: #bbbbbb } /* Text.Whitespace */
.pygmentize_8U2Wb9 .mf { color: #009999 } /* Literal.Number.Float */
.pygmentize_8U2Wb9 .mh { color: #009999 } /* Literal.Number.Hex */
.pygmentize_8U2Wb9 .mi { color: #009999 } /* Literal.Number.Integer */
.pygmentize_8U2Wb9 .mo { color: #009999 } /* Literal.Number.Oct */
.pygmentize_8U2Wb9 .sb { color: #d01040 } /* Literal.String.Backtick */
.pygmentize_8U2Wb9 .sc { color: #d01040 } /* Literal.String.Char */
.pygmentize_8U2Wb9 .sd { color: #d01040 } /* Literal.String.Doc */
.pygmentize_8U2Wb9 .s2 { color: #d01040 } /* Literal.String.Double */
.pygmentize_8U2Wb9 .se { color: #d01040 } /* Literal.String.Escape */
.pygmentize_8U2Wb9 .sh { color: #d01040 } /* Literal.String.Heredoc */
.pygmentize_8U2Wb9 .si { color: #d01040 } /* Literal.String.Interpol */
.pygmentize_8U2Wb9 .sx { color: #d01040 } /* Literal.String.Other */
.pygmentize_8U2Wb9 .sr { color: #009926 } /* Literal.String.Regex */
.pygmentize_8U2Wb9 .s1 { color: #d01040 } /* Literal.String.Single */
.pygmentize_8U2Wb9 .ss { color: #990073 } /* Literal.String.Symbol */
.pygmentize_8U2Wb9 .bp { color: #999999 } /* Name.Builtin.Pseudo */
.pygmentize_8U2Wb9 .vc { color: #008080 } /* Name.Variable.Class */
.pygmentize_8U2Wb9 .vg { color: #008080 } /* Name.Variable.Global */
.pygmentize_8U2Wb9 .vi { color: #008080 } /* Name.Variable.Instance */
.pygmentize_8U2Wb9 .il { color: #009999 } /* Literal.Number.Integer.Long */

  </style>




<div class="pygmentize_8U2Wb9"><pre><span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nx">i</span><span class="o"><</span><span class="nx">usuario</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">){</span>
<span class="kd">var</span> <span class="nx">caracter</span> <span class="o">=</span> <span class="nx">usuario</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
<span class="nx">k</span> <span class="o">=</span> <span class="nx">k</span> <span class="o">+</span> <span class="nx">$</span><span class="p">(</span><span class="nx">caracter</span><span class="p">).</span><span class="nx">value</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">var</span> <span class="nx">letras</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Array</span><span class="p">();</span>

<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span><span class="o">=</span><span class="mi">32</span><span class="p">;</span> <span class="nx">i</span><span class="o"><</span><span class="mi">170</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">){</span>

<span class="nx">letras</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">i</span><span class="p">);</span>

<span class="p">}</span>
</pre></div>


</div>
<div class="twocol-one last">
<p><style type="text/css">


/* *************************************************** */
/* WordPress default theme "twenty-ten" compatibility: */
/* FIXME: Is there a way to limit these changes to pygmentize_ahuDbw  */
/*        without editing the WordPress theme directly? */
/* *************************************************** */

#content pre {
  /* The background: transparent is needed to work with WordPress:*/
  background: transparent;
  /* Default WordPress style has a big fat <pre> margin-bottom: */
  margin-bottom: 20px;

  /*color: #333333;*/
  font-size: .9em; 
  line-height: 1.25em;
}

#content table {
}

#content table {
	border: 1px solid #e7e7e7;
    margin: 0 0 0 0;
	text-align: left;
	width: 100%;
}
#content tr th,
#content thead th {
	color: #888;
	font-size: 12px;
	font-weight: bold;
	line-height: 18px;
	padding: 0px;
}
#content tr td {
	border: 0px;
	padding: 0px;
	margin: 0px;
    margin-bottom: 0px;
    padding-bottom: 0px;

}

/* *************************************************** */
/* *************************************************** */

/* Standard fixes to the default output: */

/* Set the tab width in "ch" character units: */
.pygmentize_ahuDbw .tabspan {
  display: inline-block;
  width: 4ch;
}

.pygmentize_ahuDbw  {
  border:3px solid #EEE;
}

.pygmentize_ahuDbw pre {
  margin-left:20px;
  margin-top:20px;
  margin-bottom:20px;
}

/* When using line numbers, use 100% table width and no cellpadding: */
.pygmentize_ahuDbwtable {
  width: 100%;
  border-spacing: 0px;
  border-collapse: collapse;
}


/*
#content table {
    border: 1px solid #E7E7E7;
    margin: 0 -1px 24px 0;
    text-align: left;
    width: 100%;
}
*/

.pygmentize_ahuDbwtable td, .pygmentize_ahuDbwtable th {
  padding: 0px;
  margin: 0px;
}

/* Add a little buffer so the monotype font doesn't bump directly against the edge: */
.pygmentize_ahuDbw pre {
  padding: .6ch;
  
}

/* This is more consistent with <p> tags... I didn't like it for my use: */
/*
div .pygmentize_ahuDbw {
    margin-bottom: 24px; 
}
*/

td.linenos.pygmentize_ahuDbw {
  width: 1ch;
  padding: .6ch;
  line-height: 1.25em;
}

.pygmentize_ahuDbw td {
  padding-right: 1px;
}


td.linenos { background-color: #f0f0f0; padding-right: 1px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
pre { line-height: 125%; }
.pygmentize_ahuDbw .hll { background-color: #ffffcc }
.pygmentize_ahuDbw  { background: #ffffff; }
.pygmentize_ahuDbw .c { color: #999988; font-style: italic } /* Comment */
.pygmentize_ahuDbw .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.pygmentize_ahuDbw .k { color: #000000; font-weight: bold } /* Keyword */
.pygmentize_ahuDbw .o { color: #000000; font-weight: bold } /* Operator */
.pygmentize_ahuDbw .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.pygmentize_ahuDbw .cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */
.pygmentize_ahuDbw .c1 { color: #999988; font-style: italic } /* Comment.Single */
.pygmentize_ahuDbw .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.pygmentize_ahuDbw .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.pygmentize_ahuDbw .ge { color: #000000; font-style: italic } /* Generic.Emph */
.pygmentize_ahuDbw .gr { color: #aa0000 } /* Generic.Error */
.pygmentize_ahuDbw .gh { color: #999999 } /* Generic.Heading */
.pygmentize_ahuDbw .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.pygmentize_ahuDbw .go { color: #888888 } /* Generic.Output */
.pygmentize_ahuDbw .gp { color: #555555 } /* Generic.Prompt */
.pygmentize_ahuDbw .gs { font-weight: bold } /* Generic.Strong */
.pygmentize_ahuDbw .gu { color: #aaaaaa } /* Generic.Subheading */
.pygmentize_ahuDbw .gt { color: #aa0000 } /* Generic.Traceback */
.pygmentize_ahuDbw .kc { color: #000000; font-weight: bold } /* Keyword.Constant */
.pygmentize_ahuDbw .kd { color: #000000; font-weight: bold } /* Keyword.Declaration */
.pygmentize_ahuDbw .kn { color: #000000; font-weight: bold } /* Keyword.Namespace */
.pygmentize_ahuDbw .kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */
.pygmentize_ahuDbw .kr { color: #000000; font-weight: bold } /* Keyword.Reserved */
.pygmentize_ahuDbw .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.pygmentize_ahuDbw .m { color: #009999 } /* Literal.Number */
.pygmentize_ahuDbw .s { color: #d01040 } /* Literal.String */
.pygmentize_ahuDbw .na { color: #008080 } /* Name.Attribute */
.pygmentize_ahuDbw .nb { color: #0086B3 } /* Name.Builtin */
.pygmentize_ahuDbw .nc { color: #445588; font-weight: bold } /* Name.Class */
.pygmentize_ahuDbw .no { color: #008080 } /* Name.Constant */
.pygmentize_ahuDbw .nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */
.pygmentize_ahuDbw .ni { color: #800080 } /* Name.Entity */
.pygmentize_ahuDbw .ne { color: #990000; font-weight: bold } /* Name.Exception */
.pygmentize_ahuDbw .nf { color: #990000; font-weight: bold } /* Name.Function */
.pygmentize_ahuDbw .nl { color: #990000; font-weight: bold } /* Name.Label */
.pygmentize_ahuDbw .nn { color: #555555 } /* Name.Namespace */
.pygmentize_ahuDbw .nt { color: #000080 } /* Name.Tag */
.pygmentize_ahuDbw .nv { color: #008080 } /* Name.Variable */
.pygmentize_ahuDbw .ow { color: #000000; font-weight: bold } /* Operator.Word */
.pygmentize_ahuDbw .w { color: #bbbbbb } /* Text.Whitespace */
.pygmentize_ahuDbw .mf { color: #009999 } /* Literal.Number.Float */
.pygmentize_ahuDbw .mh { color: #009999 } /* Literal.Number.Hex */
.pygmentize_ahuDbw .mi { color: #009999 } /* Literal.Number.Integer */
.pygmentize_ahuDbw .mo { color: #009999 } /* Literal.Number.Oct */
.pygmentize_ahuDbw .sb { color: #d01040 } /* Literal.String.Backtick */
.pygmentize_ahuDbw .sc { color: #d01040 } /* Literal.String.Char */
.pygmentize_ahuDbw .sd { color: #d01040 } /* Literal.String.Doc */
.pygmentize_ahuDbw .s2 { color: #d01040 } /* Literal.String.Double */
.pygmentize_ahuDbw .se { color: #d01040 } /* Literal.String.Escape */
.pygmentize_ahuDbw .sh { color: #d01040 } /* Literal.String.Heredoc */
.pygmentize_ahuDbw .si { color: #d01040 } /* Literal.String.Interpol */
.pygmentize_ahuDbw .sx { color: #d01040 } /* Literal.String.Other */
.pygmentize_ahuDbw .sr { color: #009926 } /* Literal.String.Regex */
.pygmentize_ahuDbw .s1 { color: #d01040 } /* Literal.String.Single */
.pygmentize_ahuDbw .ss { color: #990073 } /* Literal.String.Symbol */
.pygmentize_ahuDbw .bp { color: #999999 } /* Name.Builtin.Pseudo */
.pygmentize_ahuDbw .vc { color: #008080 } /* Name.Variable.Class */
.pygmentize_ahuDbw .vg { color: #008080 } /* Name.Variable.Global */
.pygmentize_ahuDbw .vi { color: #008080 } /* Name.Variable.Instance */
.pygmentize_ahuDbw .il { color: #009999 } /* Literal.Number.Integer.Long */

  </style>




<div class="pygmentize_ahuDbw"><pre><span class="k">for</span> <span class="nx">caracter</span> <span class="k">in</span> <span class="nx">usuario</span>
<span class="nv">k = </span><span class="nx">k</span> <span class="o">+</span> <span class="nx">$</span><span class="p">(</span><span class="nx">caracter</span><span class="p">).</span><span class="nx">value</span>

<span class="nv">letras = </span><span class="p">(</span><span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">i</span><span class="p">)</span> <span class="k">for</span> <span class="nx">i</span> <span class="k">in</span> <span class="p">[</span><span class="mi">32</span><span class="p">..</span><span class="mi">169</span><span class="p">])</span>
</pre></div>

<br />
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h3 style="text-align: justify;">Sentencias repetitivas</h3>
<p >El clasico de toda la vida <code>for</code> se abrevia, ya no necesitamos conocer la longitud del arreglo a iterar, ni definir alguna variable auxiliar,CoffeeScript se encarga de todo eso.</p>
<h3 style="text-align: justify;">Arreglos</h3>
<p>Para crear un arreglo basta utilizar <code>nombre = []</code> aunque para el ejemplo que tenemos creamos un arreglo a partir de una sentencia for y un rango.</p>
<h3>Rangos</h3>
<p >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 <code>[inicio..final] </code>. 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 (&#8230;) significa que el extremo final del rango es excluido.</p>
<h2>El resultado final</h2>
<p>Y finalmente!! mi Javascript bookmarklet migrado a CoffeeScript</p>
<style type="text/css">


/* *************************************************** */
/* WordPress default theme "twenty-ten" compatibility: */
/* FIXME: Is there a way to limit these changes to pygmentize_91n2tT  */
/*        without editing the WordPress theme directly? */
/* *************************************************** */

#content pre {
  /* The background: transparent is needed to work with WordPress:*/
  background: transparent;
  /* Default WordPress style has a big fat <pre> margin-bottom: */
  margin-bottom: 20px;

  /*color: #333333;*/
  font-size: .9em; 
  line-height: 1.25em;
}

#content table {
}

#content table {
	border: 1px solid #e7e7e7;
    margin: 0 0 0 0;
	text-align: left;
	width: 100%;
}
#content tr th,
#content thead th {
	color: #888;
	font-size: 12px;
	font-weight: bold;
	line-height: 18px;
	padding: 0px;
}
#content tr td {
	border: 0px;
	padding: 0px;
	margin: 0px;
    margin-bottom: 0px;
    padding-bottom: 0px;

}

/* *************************************************** */
/* *************************************************** */

/* Standard fixes to the default output: */

/* Set the tab width in "ch" character units: */
.pygmentize_91n2tT .tabspan {
  display: inline-block;
  width: 4ch;
}

.pygmentize_91n2tT  {
  border:3px solid #EEE;
}

.pygmentize_91n2tT pre {
  margin-left:20px;
  margin-top:20px;
  margin-bottom:20px;
}

/* When using line numbers, use 100% table width and no cellpadding: */
.pygmentize_91n2tTtable {
  width: 100%;
  border-spacing: 0px;
  border-collapse: collapse;
}


/*
#content table {
    border: 1px solid #E7E7E7;
    margin: 0 -1px 24px 0;
    text-align: left;
    width: 100%;
}
*/

.pygmentize_91n2tTtable td, .pygmentize_91n2tTtable th {
  padding: 0px;
  margin: 0px;
}

/* Add a little buffer so the monotype font doesn't bump directly against the edge: */
.pygmentize_91n2tT pre {
  padding: .6ch;
  
}

/* This is more consistent with <p> tags... I didn't like it for my use: */
/*
div .pygmentize_91n2tT {
    margin-bottom: 24px; 
}
*/

td.linenos.pygmentize_91n2tT {
  width: 1ch;
  padding: .6ch;
  line-height: 1.25em;
}

.pygmentize_91n2tT td {
  padding-right: 1px;
}


td.linenos { background-color: #f0f0f0; padding-right: 1px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
pre { line-height: 125%; }
.pygmentize_91n2tT .hll { background-color: #ffffcc }
.pygmentize_91n2tT  { background: #ffffff; }
.pygmentize_91n2tT .c { color: #999988; font-style: italic } /* Comment */
.pygmentize_91n2tT .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.pygmentize_91n2tT .k { color: #000000; font-weight: bold } /* Keyword */
.pygmentize_91n2tT .o { color: #000000; font-weight: bold } /* Operator */
.pygmentize_91n2tT .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.pygmentize_91n2tT .cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */
.pygmentize_91n2tT .c1 { color: #999988; font-style: italic } /* Comment.Single */
.pygmentize_91n2tT .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.pygmentize_91n2tT .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.pygmentize_91n2tT .ge { color: #000000; font-style: italic } /* Generic.Emph */
.pygmentize_91n2tT .gr { color: #aa0000 } /* Generic.Error */
.pygmentize_91n2tT .gh { color: #999999 } /* Generic.Heading */
.pygmentize_91n2tT .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.pygmentize_91n2tT .go { color: #888888 } /* Generic.Output */
.pygmentize_91n2tT .gp { color: #555555 } /* Generic.Prompt */
.pygmentize_91n2tT .gs { font-weight: bold } /* Generic.Strong */
.pygmentize_91n2tT .gu { color: #aaaaaa } /* Generic.Subheading */
.pygmentize_91n2tT .gt { color: #aa0000 } /* Generic.Traceback */
.pygmentize_91n2tT .kc { color: #000000; font-weight: bold } /* Keyword.Constant */
.pygmentize_91n2tT .kd { color: #000000; font-weight: bold } /* Keyword.Declaration */
.pygmentize_91n2tT .kn { color: #000000; font-weight: bold } /* Keyword.Namespace */
.pygmentize_91n2tT .kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */
.pygmentize_91n2tT .kr { color: #000000; font-weight: bold } /* Keyword.Reserved */
.pygmentize_91n2tT .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.pygmentize_91n2tT .m { color: #009999 } /* Literal.Number */
.pygmentize_91n2tT .s { color: #d01040 } /* Literal.String */
.pygmentize_91n2tT .na { color: #008080 } /* Name.Attribute */
.pygmentize_91n2tT .nb { color: #0086B3 } /* Name.Builtin */
.pygmentize_91n2tT .nc { color: #445588; font-weight: bold } /* Name.Class */
.pygmentize_91n2tT .no { color: #008080 } /* Name.Constant */
.pygmentize_91n2tT .nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */
.pygmentize_91n2tT .ni { color: #800080 } /* Name.Entity */
.pygmentize_91n2tT .ne { color: #990000; font-weight: bold } /* Name.Exception */
.pygmentize_91n2tT .nf { color: #990000; font-weight: bold } /* Name.Function */
.pygmentize_91n2tT .nl { color: #990000; font-weight: bold } /* Name.Label */
.pygmentize_91n2tT .nn { color: #555555 } /* Name.Namespace */
.pygmentize_91n2tT .nt { color: #000080 } /* Name.Tag */
.pygmentize_91n2tT .nv { color: #008080 } /* Name.Variable */
.pygmentize_91n2tT .ow { color: #000000; font-weight: bold } /* Operator.Word */
.pygmentize_91n2tT .w { color: #bbbbbb } /* Text.Whitespace */
.pygmentize_91n2tT .mf { color: #009999 } /* Literal.Number.Float */
.pygmentize_91n2tT .mh { color: #009999 } /* Literal.Number.Hex */
.pygmentize_91n2tT .mi { color: #009999 } /* Literal.Number.Integer */
.pygmentize_91n2tT .mo { color: #009999 } /* Literal.Number.Oct */
.pygmentize_91n2tT .sb { color: #d01040 } /* Literal.String.Backtick */
.pygmentize_91n2tT .sc { color: #d01040 } /* Literal.String.Char */
.pygmentize_91n2tT .sd { color: #d01040 } /* Literal.String.Doc */
.pygmentize_91n2tT .s2 { color: #d01040 } /* Literal.String.Double */
.pygmentize_91n2tT .se { color: #d01040 } /* Literal.String.Escape */
.pygmentize_91n2tT .sh { color: #d01040 } /* Literal.String.Heredoc */
.pygmentize_91n2tT .si { color: #d01040 } /* Literal.String.Interpol */
.pygmentize_91n2tT .sx { color: #d01040 } /* Literal.String.Other */
.pygmentize_91n2tT .sr { color: #009926 } /* Literal.String.Regex */
.pygmentize_91n2tT .s1 { color: #d01040 } /* Literal.String.Single */
.pygmentize_91n2tT .ss { color: #990073 } /* Literal.String.Symbol */
.pygmentize_91n2tT .bp { color: #999999 } /* Name.Builtin.Pseudo */
.pygmentize_91n2tT .vc { color: #008080 } /* Name.Variable.Class */
.pygmentize_91n2tT .vg { color: #008080 } /* Name.Variable.Global */
.pygmentize_91n2tT .vi { color: #008080 } /* Name.Variable.Instance */
.pygmentize_91n2tT .il { color: #009999 } /* Literal.Number.Integer.Long */

  </style>




<div class="pygmentize_91n2tT"><pre><span class="c1">#declaracion de variables</span>
<span class="nv">ifr = </span><span class="kc">no</span><span class="p">;</span>
<span class="nv">formName = </span><span class="s1">&#39;loginForm&#39;</span><span class="p">;</span>
<span class="c1">#funciones</span>
<span class="nv">iisIframe = </span><span class="o">-></span>
<span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">href</span><span class="o">==</span><span class="s1">&#39;https://www.pcbac.com/PotalaPersonal/home.do&#39;</span><span class="p">;</span>
<span class="nb">window</span><span class="p">.</span><span class="nv">iisIframe = </span><span class="nx">iisIframe</span>

<span class="c1">#Ojo con los espacios es importante!!!</span>
<span class="nv">$ = </span><span class="nf">(idname) -></span>
<span class="nv">doc = </span><span class="k">if</span> <span class="nx">ifr</span> <span class="k">then</span> <span class="nb">window</span><span class="p">.</span><span class="nx">frames</span><span class="p">.</span><span class="nx">working</span><span class="p">.</span><span class="nb">document</span> <span class="k">else</span> <span class="nb">document</span> <span class="c1">#if else</span>
<span class="nx">doc</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="nx">idname</span><span class="p">)</span> <span class="o">or</span>
<span class="nx">doc</span><span class="p">.</span><span class="nx">getElementsByName</span><span class="p">(</span><span class="nx">idname</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="o">or</span> <span class="s1">&#39;&#39;</span>

<span class="nb">window</span><span class="p">.</span><span class="nv">$ = </span><span class="nx">$</span><span class="p">;</span>

<span class="nv">createHTMLElement = </span><span class="nf">(id,type) -></span>
<span class="nv">_parent = </span><span class="nx">$</span><span class="p">(</span><span class="nx">id</span><span class="p">).</span><span class="nx">parentNode</span>
<span class="nv">_parent.innerHTML = </span><span class="s1">&#39;&#39;</span>
<span class="nv">_input = </span><span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span> <span class="s1">&#39;input&#39;</span>
<span class="nx">_input</span><span class="p">.</span><span class="nx">setAttribute</span> <span class="s1">&#39;type&#39;</span><span class="p">,</span> <span class="nx">type</span>
<span class="nx">_input</span><span class="p">.</span><span class="nx">setAttribute</span> <span class="s1">&#39;id&#39;</span><span class="p">,</span> <span class="nx">id</span>
<span class="nx">_input</span><span class="p">.</span><span class="nx">setAttribute</span> <span class="s1">&#39;name&#39;</span><span class="p">,</span> <span class="nx">id</span>
<span class="nx">_input</span><span class="p">.</span><span class="nx">setAttribute</span> <span class="s1">&#39;size&#39;</span><span class="p">,</span> <span class="s1">&#39;32&#39;</span>
<span class="nx">_input</span><span class="p">.</span><span class="nx">setAttribute</span> <span class="s1">&#39;autocomplete&#39;</span><span class="p">,</span> <span class="s1">&#39;off&#39;</span> <span class="c1">#los parentesis no son necesarios</span>
<span class="nx">_input</span><span class="p">.</span><span class="nx">setAttribute</span> <span class="s1">&#39;class&#39;</span><span class="p">,</span> <span class="s1">&#39;notfocussed&#39;</span>
<span class="nx">_input</span><span class="p">.</span><span class="nx">setAttribute</span> <span class="s1">&#39;onblur&#39;</span><span class="p">,</span> <span class="k">if</span> <span class="nx">ifr</span> <span class="k">then</span> <span class="s1">&#39;parent.copyText(this);&#39;</span> <span class="k">else</span> <span class="s1">&#39;copyText(this);&#39;</span>
<span class="nx">_parent</span><span class="p">.</span><span class="nx">appendChild</span> <span class="nx">_input</span>
<span class="k">return</span> <span class="c1">#coloco esto para que mi funcion no retorne nada</span>

<span class="nb">window</span><span class="p">.</span><span class="nv">createHTMLElement = </span><span class="nx">createHTMLElement</span>

<span class="nv">copyText = </span><span class="nf">(caja) -></span>
<span class="nv">usuario = </span><span class="nx">caja</span><span class="p">.</span><span class="nx">value</span>
<span class="nv">k = </span><span class="s1">&#39;&#39;</span>
<span class="k">for</span> <span class="nx">caracter</span> <span class="k">in</span> <span class="nx">usuario</span>
<span class="nv">k = </span><span class="nx">k</span> <span class="o">+</span> <span class="nx">$</span><span class="p">(</span><span class="nx">caracter</span><span class="p">).</span><span class="nx">value</span>

<span class="k">if</span> <span class="nx">caja</span><span class="p">.</span><span class="nx">id</span><span class="o">==</span><span class="s1">&#39;usernameA&#39;</span> <span class="o">or</span> <span class="nx">caja</span><span class="p">.</span><span class="nx">id</span><span class="o">==</span><span class="s1">&#39;claveActual&#39;</span> <span class="k">then</span> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;Field1ValueHidden&#39;</span><span class="p">).</span><span class="nv">value = </span><span class="nx">k</span>
<span class="k">if</span> <span class="nx">caja</span><span class="p">.</span><span class="nx">id</span><span class="o">==</span><span class="s1">&#39;passwordA&#39;</span> <span class="o">or</span> <span class="nx">caja</span><span class="p">.</span><span class="nx">id</span><span class="o">==</span><span class="s1">&#39;nuevaClave&#39;</span> <span class="k">then</span> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;Field2ValueHidden&#39;</span><span class="p">).</span><span class="nv">value = </span><span class="nx">k</span>
<span class="k">if</span> <span class="nx">caja</span><span class="p">.</span><span class="nx">id</span><span class="o">==</span><span class="s1">&#39;confirmacionNuevaClave&#39;</span> <span class="k">then</span> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;Field3ValueHidden&#39;</span><span class="p">).</span><span class="nv">value = </span><span class="nx">k</span>

<span class="k">return</span>

<span class="nb">window</span><span class="p">.</span><span class="nv">copyText = </span><span class="nx">copyText</span><span class="p">;</span>

<span class="nx">ifr</span><span class="o">=</span><span class="nx">iisIframe</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">ifr</span> <span class="k">then</span> <span class="nx">formName</span><span class="o">=</span><span class="s1">&#39;cambioClaveForm&#39;</span>
<span class="nv">firstRowSplit = </span><span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">charFirstRowhidden</span><span class="p">.</span><span class="nx">value</span>
<span class="nv">secondRowSplit = </span><span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">charSecondRowhidden</span><span class="p">.</span><span class="nx">value</span>
<span class="nv">thirdRowSplit = </span><span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">charThirdRowhidden</span><span class="p">.</span><span class="nx">value</span>
<span class="nv">firstRowSplitMi = </span><span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">charFirstRowhiddenHMi</span><span class="p">.</span><span class="nx">value</span>
<span class="nv">secondRowSplitMi = </span><span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">charSecondRowhiddenHMi</span><span class="p">.</span><span class="nx">value</span>
<span class="nv">thirdRowSplitMi = </span><span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">charThirdRowhiddenHMi</span><span class="p">.</span><span class="nx">value</span>
<span class="nv">firstRowSplitMa = </span><span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">charFirstRowhiddenHMa</span><span class="p">.</span><span class="nx">value</span>
<span class="nv">secondRowSplitMa = </span><span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">charSecondRowhiddenHMa</span><span class="p">.</span><span class="nx">value</span>
<span class="nv">thirdRowSplitMa = </span><span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">charThirdRowhiddenHMa</span><span class="p">.</span><span class="nx">value</span>

<span class="nv">firstRow = </span><span class="nx">firstRowSplit</span><span class="p">.</span><span class="nx">split</span> <span class="s1">&#39;|&#39;</span>
<span class="nv">firstRowMi = </span><span class="nx">firstRowSplitMi</span><span class="p">.</span><span class="nx">split</span> <span class="s1">&#39;|&#39;</span>
<span class="nv">firstRowMa = </span><span class="nx">firstRowSplitMa</span><span class="p">.</span><span class="nx">split</span> <span class="s1">&#39;|&#39;</span>
<span class="nv">secondRow = </span><span class="nx">secondRowSplit</span><span class="p">.</span><span class="nx">split</span> <span class="s1">&#39;|&#39;</span>
<span class="nv">secondRowMi = </span><span class="nx">secondRowSplitMi</span><span class="p">.</span><span class="nx">split</span> <span class="s1">&#39;|&#39;</span>
<span class="nv">secondRowMa = </span><span class="nx">secondRowSplitMa</span><span class="p">.</span><span class="nx">split</span> <span class="s1">&#39;|&#39;</span>
<span class="nv">thirdRow = </span><span class="nx">thirdRowSplit</span><span class="p">.</span><span class="nx">split</span> <span class="s1">&#39;|&#39;</span>
<span class="nv">thirdRowMi = </span><span class="nx">thirdRowSplitMi</span><span class="p">.</span><span class="nx">split</span> <span class="s1">&#39;|&#39;</span>
<span class="nv">thirdRowMa = </span><span class="nx">thirdRowSplitMa</span><span class="p">.</span><span class="nx">split</span> <span class="s1">&#39;|&#39;</span>
<span class="nv">todo = </span><span class="p">[]</span>
<span class="k">for</span> <span class="nx">i</span> <span class="k">in</span> <span class="p">[</span><span class="nx">firstRow</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">..</span><span class="mi">0</span><span class="p">]</span> <span class="k">by</span> <span class="o">-</span><span class="mi">1</span> <span class="c1">#empezar en -1</span>
<span class="nx">todo</span><span class="p">[</span><span class="nx">firstRow</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">toLowerCase</span><span class="p">()]</span> <span class="o">=</span> <span class="nx">firstRowMi</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span><span class="nx">todo</span><span class="p">[</span><span class="nx">firstRow</span><span class="p">[</span><span class="nx">i</span><span class="p">]]</span> <span class="o">=</span> <span class="nx">firstRowMa</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
<span class="k">for</span> <span class="nx">i</span> <span class="k">in</span> <span class="p">[</span><span class="nx">secondRow</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">..</span><span class="mi">0</span><span class="p">]</span> <span class="k">by</span> <span class="o">-</span><span class="mi">1</span>
<span class="nx">todo</span><span class="p">[</span><span class="nx">secondRow</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">toLowerCase</span><span class="p">()]</span> <span class="o">=</span> <span class="nx">secondRowMi</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span><span class="nx">todo</span><span class="p">[</span><span class="nx">secondRow</span><span class="p">[</span><span class="nx">i</span><span class="p">]]</span> <span class="o">=</span> <span class="nx">secondRowMa</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
<span class="k">for</span> <span class="nx">i</span> <span class="k">in</span> <span class="p">[</span><span class="nx">thirdRow</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">..</span><span class="mi">0</span><span class="p">]</span> <span class="k">by</span> <span class="o">-</span><span class="mi">1</span>
<span class="nx">todo</span><span class="p">[</span><span class="nx">thirdRow</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">toLowerCase</span><span class="p">()]</span> <span class="o">=</span> <span class="nx">thirdRowMi</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span><span class="nx">todo</span><span class="p">[</span><span class="nx">thirdRow</span><span class="p">[</span><span class="nx">i</span><span class="p">]]</span> <span class="o">=</span> <span class="nx">thirdRowMa</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>

<span class="k">for</span> <span class="nx">m</span> <span class="k">in</span> <span class="p">[</span><span class="mi">0</span><span class="p">..</span><span class="mi">2</span><span class="p">]</span>
<span class="nx">todo</span><span class="p">[</span><span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">number1</span><span class="p">[</span><span class="nx">m</span><span class="p">].</span><span class="nx">value</span><span class="p">]</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">number1</span><span class="p">[</span><span class="nx">m</span><span class="p">].</span><span class="nx">alt</span><span class="p">;</span>
<span class="nx">todo</span><span class="p">[</span><span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">number2</span><span class="p">[</span><span class="nx">m</span><span class="p">].</span><span class="nx">value</span><span class="p">]</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">number2</span><span class="p">[</span><span class="nx">m</span><span class="p">].</span><span class="nx">alt</span><span class="p">;</span>
<span class="nx">todo</span><span class="p">[</span><span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">number3</span><span class="p">[</span><span class="nx">m</span><span class="p">].</span><span class="nx">value</span><span class="p">]</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">number3</span><span class="p">[</span><span class="nx">m</span><span class="p">].</span><span class="nx">alt</span><span class="p">;</span>

<span class="nx">todo</span><span class="p">[</span><span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">number4</span><span class="p">.</span><span class="nx">value</span><span class="p">]</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">number4</span><span class="p">.</span><span class="nx">alt</span><span class="p">;</span>

<span class="k">for</span> <span class="nx">m</span> <span class="k">in</span> <span class="p">[</span><span class="mi">0</span><span class="p">..</span><span class="mi">9</span><span class="p">]</span>
<span class="nx">todo</span><span class="p">[</span><span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">button4</span><span class="p">[</span><span class="nx">m</span><span class="p">].</span><span class="nx">value</span><span class="p">]</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">button4</span><span class="p">[</span><span class="nx">m</span><span class="p">].</span><span class="nx">alt</span><span class="p">;</span>

<span class="k">for</span> <span class="nx">m</span> <span class="k">in</span> <span class="p">[</span><span class="mi">0</span><span class="p">..</span><span class="mi">10</span><span class="p">]</span>
<span class="nx">todo</span><span class="p">[</span><span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">button5</span><span class="p">[</span><span class="nx">m</span><span class="p">].</span><span class="nx">value</span><span class="p">]</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">button5</span><span class="p">[</span><span class="nx">m</span><span class="p">].</span><span class="nx">alt</span><span class="p">;</span>
<span class="nx">todo</span><span class="p">[</span><span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">button10</span><span class="p">[</span><span class="nx">m</span><span class="p">].</span><span class="nx">value</span><span class="p">]</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">button10</span><span class="p">[</span><span class="nx">m</span><span class="p">].</span><span class="nx">alt</span><span class="p">;</span>

<span class="nv">letras = </span><span class="p">(</span><span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">(</span><span class="nx">i</span><span class="p">)</span> <span class="k">for</span> <span class="nx">i</span> <span class="k">in</span> <span class="p">[</span><span class="mi">32</span><span class="p">..</span><span class="mi">169</span><span class="p">])</span>

<span class="k">for</span> <span class="nx">letra</span> <span class="k">in</span> <span class="nx">letras</span>
<span class="nv">input = </span><span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span> <span class="s1">&#39;input&#39;</span>
<span class="nx">input</span><span class="p">.</span><span class="nx">setAttribute</span> <span class="s1">&#39;type&#39;</span><span class="p">,</span> <span class="s1">&#39;hidden&#39;</span>
<span class="nx">input</span><span class="p">.</span><span class="nx">setAttribute</span> <span class="s1">&#39;id&#39;</span><span class="p">,</span> <span class="nx">letra</span>
<span class="nx">input</span><span class="p">.</span><span class="nx">setAttribute</span> <span class="s1">&#39;value&#39;</span><span class="p">,</span> <span class="nx">todo</span><span class="p">[</span><span class="nx">letra</span><span class="p">]</span>
<span class="nx">$</span><span class="p">(</span><span class="nx">formName</span><span class="p">).</span><span class="nx">appendChild</span> <span class="nx">input</span>

<span class="k">if</span> <span class="o">!</span><span class="nx">ifr</span>
<span class="nx">createHTMLElement</span><span class="p">(</span><span class="s1">&#39;usernameA&#39;</span><span class="p">,</span><span class="s1">&#39;text&#39;</span><span class="p">)</span>
<span class="nx">createHTMLElement</span><span class="p">(</span><span class="s1">&#39;passwordA&#39;</span><span class="p">,</span><span class="s1">&#39;password&#39;</span><span class="p">)</span>
<span class="k">else</span>
<span class="nx">createHTMLElement</span><span class="p">(</span><span class="s1">&#39;claveActual&#39;</span><span class="p">,</span><span class="s1">&#39;password&#39;</span><span class="p">)</span>
<span class="nx">createHTMLElement</span><span class="p">(</span><span class="s1">&#39;nuevaClave&#39;</span><span class="p">,</span><span class="s1">&#39;password&#39;</span><span class="p">)</span>
<span class="nx">createHTMLElement</span><span class="p">(</span><span class="s1">&#39;confirmacionNuevaClave&#39;</span><span class="p">,</span><span class="s1">&#39;password&#39;</span><span class="p">)</span>

<span class="nx">$</span><span class="p">(</span><span class="k">if</span> <span class="nx">ifr</span> <span class="k">then</span> <span class="nx">formName</span> <span class="k">else</span> <span class="s1">&#39;forma1&#39;</span><span class="p">).</span><span class="nx">getElementsByTagName</span><span class="p">(</span><span class="s2">&quot;table&quot;</span><span class="p">)[</span><span class="mi">0</span><span class="p">].</span><span class="nx">getElementsByTagName</span><span class="p">(</span><span class="s2">&quot;tr&quot;</span><span class="p">)</span>

<span class="p">[</span><span class="k">if</span> <span class="nx">ifr</span> <span class="k">then</span> <span class="mi">14</span> <span class="k">else</span> <span class="mi">8</span><span class="p">].</span><span class="nv">style.display = </span><span class="s1">&#39;none&#39;</span>
</pre></div>


<p>&nbsp;</p>
<h2>CoffeeScript es mucho mas</h2>
<p >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</p>
<p ><div class="shortcode-unorderedlist arrow"></p>
<ul>
<li><a href="http://coffeescript.org/">http://coffeescript.org/</a></li>
<li><a href="http://arcturo.github.com/library/coffeescript/">http://arcturo.github.com/library/coffeescript/</a></li>
<li><a href="http://coffeescriptcookbook.com/">http://coffeescriptcookbook.com/</a></li>
<li><a href="https://twitter.com/#!/coffeescript">https://twitter.com/#!/coffeescript</a></li>
<li><a href="http://net.tutsplus.com/articles/interviews/should-you-learn-coffeescript/">http://net.tutsplus.com/articles/interviews/should-you-learn-coffeescript/</a></li>
<li><a href="http://www.codeschool.com/courses/coffeescript">http://www.codeschool.com/courses/coffeescript</a></li>
</ul>
<p ></div>
</p>
<p ><span class="shortcode-highlight"><strong>Un curso de CoffeeScript en EscueladeCodigo, completamente gratis, ¿te parece buena idea?</strong></span><!--/.shortcode-highlight--></p>
]]></content:encoded>
		</item>
		<item>
		<title>Picando Código: ¿Y si juntamos a la comunidad de usuarios ArchLinux del Uruguay?</title>
		<link>http://feedproxy.google.com/~r/picandocodigo/~3/1rrW9HJBbC8/</link>
		<pubDate>Thu, 26 Jan 2012 12:00:58 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
		
	<category>uruguay</category>
	<category>archlinux</category>
		<guid>http://feedproxy.google.com/~r/picandocodigo/~3/1rrW9HJBbC8/</guid>
		<description><![CDATA[Lo que dice el título, ¿y si juntamos un grupo [...]]]></description>
			<content:encoded><![CDATA[<div
id="attachment_2020" class="wp-caption aligncenter" style="width: 360px"><a
href="http://picandocodigo.net/wp-content/uploads/2009/01/archlinux.png"><img
class="size-full wp-image-2020" title="ArchLinux" src="http://picandocodigo.net/wp-content/uploads/2009/01/archlinux.png" alt="ArchLinux" width="350" height="103" /></a><p
class="wp-caption-text">ArchLinux</p></div><p>Lo que dice el título, ¿y si juntamos un grupo de usuarios ArchLinux en un mismo espacio física esporádicamente y nos unimos a trabajar con algun(os) objetivo(s) en común?</p><p>En un principio pensé que la mejor forma de convocar a los usuarios a unirse en grupo era crear una lista de correo, un blog, o algo así. Pero eso son solo herramientas, preferí empezar sin mucha ambición con este post (gracias al principio de KISS). Los invito a dejar un comentario si quieren sumarse a la iniciativa. Hay que ver si hay más interesados, y después entre los que seamos vemos qué se arma <img
src='http://picandocodigo.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Se me ocurren varias razones de por qué esto es una buena idea. Una buena parte de lo positivo de ir a una reunión de personas técnicas (hackatón, conferencias y demás) es conocer a otras personas con los mismo intereses. Ni que hablar que las charlas suelen ser bastante interesantes. Si nos entretenemos leyéndonos por foros, redes sociales y blogs, mejor la vamos a pasar conversando mientras tomamos alguna cerveza y comemos alguna pizza.</p><p>A continuación listo algunos objetivos/ideas/razones más que me vienen en la cabeza sin caer en nada muy ambicioso.</p><ul><li>Aprender a empaquetar aplicaciones y buscar alguna aplicación que podríamos enviar a AUR. Es un conocimiento que viene bien, y seguramente todos han toqueteado algún PKGBUILD en algún momento. De repente sale algo interesante.</li><li>Ayudar con la traducción de la wiki, si alguien tiene algo de tiempo libre para aportar al proyecto, esta es una buena manera. (<a
href="https://wiki.archlinux.org/index.php/Getting_Involved_%28Espa%C3%B1ol%29">más ideas acá</a>)</li><li>Dar a conocer cosas interesantes que hayamos logrado, scripts, personalizaciones, etc. Ayudar con algún problema particular que algun usuario pueda tener con el sistema.</li><li>&#8220;Evangelizar&#8221; a usuarios de otras distros, ayudarles a darse cuenta que ArchLinux es la mejor distribución de GNU/Linux <img
src='http://picandocodigo.net/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /></li><li><strong>Comprar camisetas de ArchLinux</strong>. Al ser muchos, podemos conseguir un buen precio para mandar a hacer camisetas de Arch.</li><li>DRY: No repetirnos. No hay que reinventar la rueda, crear más wikis y demás información repetida. Creo que si en algún momento armamos alguna representación virtual del grupo en internet, habría que limitarse al tema de las reuniones y demás posibles organizaciones que podamos llevar a cabo. Nada de reescribir o copiar y pegar todo el conocimiento que tan bien documentado está en la <a
href="https://wiki.archlinux.org/index.php/Main_Page_(Espa%C3%B1ol)">wiki de Arch</a>.</li></ul><p>Si hay convocatoria, coordinamos una fecha y me comprometo a conseguir un lugar para reunirnos por primera vez y ver qué sale. No hay mucha idea o compromiso, simplemente juntarse a ver qué sale.</p><p>Para finalizar el post, los dejo con un texto de la wiki:</p><blockquote><p>En Biología, mutualismo es una interacción entre dos organismos en que ambos organismos obtienen beneficio. Este principio puede también ser aplicado a miembros proactivos y motivados de la comunidad de ARCH que quieren estar involucrados y contribuir a su distribución favorita GNU/Linux. Esta participación beneficia no solo a los miembros de la comunidad y sus compañeros Arches, pero también a todos los fans potenciales de Software libre y de codigo abierto</p></blockquote> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/picandocodigo?a=1rrW9HJBbC8:Vwh8odp7Gjo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/picandocodigo?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/picandocodigo?a=1rrW9HJBbC8:Vwh8odp7Gjo:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/picandocodigo?i=1rrW9HJBbC8:Vwh8odp7Gjo:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/picandocodigo?a=1rrW9HJBbC8:Vwh8odp7Gjo:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/picandocodigo?i=1rrW9HJBbC8:Vwh8odp7Gjo:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/picandocodigo/~4/1rrW9HJBbC8" height="1" width="1"/>]]></content:encoded>
		</item>
		<item>
		<title>Koalite's blog: Diseño Web Sensible y Grids CSS</title>
		<link>http://feedproxy.google.com/~r/KoalitesBlog/~3/IglusgzZ9Qc/</link>
		<pubDate>Thu, 26 Jan 2012 03:17:56 +0000</pubDate>
		<dc:creator>Juanma</dc:creator>
		
	<category>CSS</category>
	<category>other</category>
	<category>ux</category>
	<category>css grids</category>
	<category>responsive design</category>
		<guid>http://feedproxy.google.com/~r/KoalitesBlog/~3/IglusgzZ9Qc/</guid>
		<description><![CDATA[<script type="text/javascript">
				  (function() {
				    var po = document.createElement("script"); po.type = "text/javascript"; po.async = true;
				    po.src = "https://apis.google.com/js/plusone.js";
				    var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(po, s);
				  })();
				</script>Ya he dicho en alguna ocasión que me interesa bastante el tema de la experiencia de usuario, aunque luego la parte de diseño gráfico que suele llevar asociada no sea mi fuerte y acabe basándome más en la teoría que en el talento. En el mundo del diseño web últimamente está muy de moda el [...]
No hay posts relacionados.]]></description>
			<content:encoded><![CDATA[<p>Ya he dicho en <a href="http://blog.koalite.com/2011/08/user-experience-en-stackexchange/" >alguna ocasión</a> que me interesa bastante el tema de la experiencia de usuario, aunque luego la parte de diseño gráfico que suele llevar asociada no sea mi fuerte y acabe basándome más <a href="http://stackoverflow.com/questions/58807/can-a-programmer-become-a-decent-graphic-designer" >en la teoría</a> que en el talento.</p>
<p>En el mundo del diseño web últimamente <strong>está muy de moda el <a href="http://www.abookapart.com/products/responsive-web-design" >Responsive Web Design</a></strong>, que podríamos traducir como diseño sensible o más bien como &#8220;diseño que responde bien&#8221;. Se trata de intentar diseñar las <strong>páginas web para que se adapten correctamente a distintas resoluciones y formatos de pantalla</strong>, y es algo que hoy en día cobra una importancia especial con la <a href="http://blog.koalite.com/2011/09/android-%c2%bfuno-para-gobernarlos-a-todos/" title="Android: ¿Uno para gobernarlos a todos?" >gran variedad de dispositivos</a> que se usan para navegar por internet.</p>
<p>Para conseguir esto, siempre existe la opción de desarrollar distintas versiones del sitio web adaptadas a cada formato que queramos soportar, pero eso implica un trabajo adicional que no siempre merece la pena y además supone un problema cuando aparecen nuevos formatos que no teníamos previsto.</p>
<p>El <em>responsive design</em> <strong>aprovecha las características de CSS3 y <a href="http://www.w3.org/TR/css3-mediaqueries/" >media queries</a></strong> para aplicar distintos formatos en función de las características del dispositivo que está accediendo a la página.</p>
<p>Una forma muy extendida de implementar esto es <strong>estructurar la página a partir de un grid</strong> y maquetar la información ajustándola a ese grid:</p>
<div id="attachment_966" class="wp-caption aligncenter" ><a href="http://www.alistapart.com/articles/fluidgrids/"><img src="http://blog.koalite.com/wp-content/uploads/comp-areas.gif" alt="Estructura de una página basada en un grid" title="Estructura de una página basada en un grid" width="519" height="364" class="size-full wp-image-966" /></a><p class="wp-caption-text">Estructura de una página basada en un grid de 7 columnas</p></div>
<p>Una vez que tenemos la información estructurada, aplicando las técnicas CSS adecuadas es relativamente fácil conseguir adaptarlo al tamaño de pantalla del dispositivo:</p>
<div id="attachment_990" class="wp-caption aligncenter" ><a href="http://designmodo.com/responsive-design-examples/"><img src="http://blog.koalite.com/wp-content/uploads/responsive-sample.jpg" alt="Ejemplo de web adaptada a distintas resoluciones" title="responsive-sample" width="519" height="294" class="size-full wp-image-990" /></a><p class="wp-caption-text">Ejemplo de web adaptada a distintas resoluciones</p></div>
<p>En este ejemplo se ve como <strong>al reducir el ancho de la pantalla, el contenido se reformatea reduciendo el tamaño de las columnas del grid, llegando incluso a apilar las columnas</strong> para pasar a un formato completamente vertical apto para teléfonos móviles. Se puede comprobar fácilmente <a href="http://foodsense.is/" >accediendo a la página</a> y redimensionando la ventana del navegador.</p>
<p>Para ayudarnos a implementar esto, <strong>existen muchos frameworks CSS para <em>responsive design</em></strong> que nos facilitan bastante la vida. Algunos están basados en <strong>grids fluidos</strong>, en los cuales la anchura de las columnas se ajusta automáticamente al tamaño de la pantalla, y otros en <strong>grids fijos</strong>, que mantienen constante la anchura de las columnas pero varían el número de columnas en función del tamaño de la pantalla. Entre los frameworks más conocidos están:</p>
<ul>
<li><a href="http://lessframework.com/" >Less framework</a></li>
<li><a href="http://cssgrid.net/" >1140 CSS Grid</a></li>
<li><a href="http://foundation.zurb.com/" >Foundation</a></li>
<li><a href="http://www.getskeleton.com/" >Skeleton</a></li>
<li><a href="http://semantic.gs/" >Semantic Grid System</a></li>
</ul>
<p>Personalmente me parece una idea bastante buena, pero <strong>hay puntos que no acaban de gustarme</strong>. Me parece que <strong>se sacrifica parte del contenido semántico</strong> del documento en favor de la maquetación, algo que ya ocurría hace unos cuantos años con el abuso de las tablas. Ahora parece que, mientras se usen <code>div</code>s en lugar de tablas, todo vale. </p>
<p>Por otra parte, casi todos estos sistemas <strong>utilizan clases CSS que no tiene valor semántico</strong>, sólo tienen valor para formatear la información. En un mundo ideal, las clases CSS que aparecen en el documento HTML no deberían definir el <em>cómo</em> (formato) sino el <em>qué</em> (intención), deberían ser algo declarativo. </p>
<p>Por ejemplo, si en una página queremos marcar el importe total de una compra, deberíamos marcarlo como <code><span class="total-amount"></code> y luego asignar en la hoja de estilo a la clase <code>total-amount</code> una fuente negrita, más grande o lo que queramos. Con este tipo de frameworks se fomenta más usar algo de la forma <code><span class="big-font red underlined"></code>, penalizando la estructura semántica del documento. Es lo mismo que ocurre al utilizar otros frameworks de diseño web como <a href="http://jqueryui.com/" >jquery-ui</a> o <a href="http://jquerymobile.com/" >jquery-mobile</a>.</p>
<p>Una excepción a esto es <strong><a href="http://semantic.gs/" >Semantic Grid System</a>, que intenta no manchar el documento html con sus clases CSS</strong>. Para ello, aplica sus estilos mediante <em>mixins</em> con <a href="http://lesscss.org/" >LESS</a>, <a href="http://sass-lang.com/" >SCSS</a> o <a href="http://learnboost.github.com/stylus/" >Stylus</a>.</p>
<p>En cualquier caso, <strong>las ventajas que aportan el uso de este tipo de frameworks son considerables</strong>, por lo que a veces resulta mejor ser más pragmático y aprovecharlos. A fin de cuentas, lo que realmente importa es aportar valor al usuario/negocio, y para ello estos frameworks pueden ser de mucha ayuda.</p>
<div class="trackable_sharing"><div class="trackable_sharing_text"><b><br/><br/><br/>Compartir enlace:
</b></div><a href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fblog.koalite.com%2F2012%2F01%2Fdiseno-web-sensible-y-grids-css%2F"  title="Facebook"  onclick="that=this;_gaq.push(['_trackEvent','SocialSharing','Facebook','http://blog.koalite.com/2012/01/diseno-web-sensible-y-grids-css/']); _trackableshare_window = window.open(this.href,'share','menubar=0,resizable=1,width=500,height=350'); _trackableshare_window.focus(); return false;"><img align="absmiddle" src="http://blog.koalite.com/wp-content/plugins/trackable-social-share-icons/buttons/f2//facebook.png" alt="Facebook" width="36" height="36"></a> <a href="http://twitter.com/share?url=http%3A%2F%2Fblog.koalite.com%2F2012%2F01%2Fdiseno-web-sensible-y-grids-css%2F&text=Dise%C3%B1o+Web+Sensible+y+Grids+CSS"  title="Twitter"  onclick="that=this;_gaq.push(['_trackEvent','SocialSharing','Twitter','http://blog.koalite.com/2012/01/diseno-web-sensible-y-grids-css/']); _trackableshare_window = window.open(this.href,'share','menubar=0,resizable=1,width=500,height=350'); _trackableshare_window.focus(); return false;"><img align="absmiddle" src="http://blog.koalite.com/wp-content/plugins/trackable-social-share-icons/buttons/f2//twitter.png" alt="Twitter" width="36" height="36"></a> <a href="mailto:?subject=Check%20out%20http%3A%2F%2Fblog.koalite.com%2F2012%2F01%2Fdiseno-web-sensible-y-grids-css%2F"  title="Email" onclick="that=this;_gaq.push(['_trackEvent','SocialSharing','Email','http://blog.koalite.com/2012/01/diseno-web-sensible-y-grids-css/']); "><img align="absmiddle" src="http://blog.koalite.com/wp-content/plugins/trackable-social-share-icons/buttons/f2//email.png" alt="Email" width="36" height="36"></a> <br /><g:plusone annotation="none"></g:plusone></div><p>No hay posts relacionados.</p><img src="http://feeds.feedburner.com/~r/KoalitesBlog/~4/IglusgzZ9Qc" height="1" width="1"/>]]></content:encoded>
		</item>
		<item>
		<title>Arragonán: Don’t Censor Me!</title>
		<link>http://feedproxy.google.com/~r/danilat/~3/SD_8lCMa33g/</link>
		<pubDate>Thu, 26 Jan 2012 00:22:50 +0000</pubDate>
		<dc:creator>Dani</dc:creator>
		
	<category>General</category>
		<guid>http://feedproxy.google.com/~r/danilat/~3/SD_8lCMa33g/</guid>
		<description><![CDATA[Via Pablo Jimeno]]></description>
			<content:encoded><![CDATA[<p><img src="http://s3.amazonaws.com/data.tumblr.com/tumblr_ly10fj0Da91r57nxno1_1280.jpg?AWSAccessKeyId=AKIAJ6IHWSU3BX3X7X3Q&#038;Expires=1327623655&#038;Signature=U64%2Fk%2FBT1XkRrR6hCNxxcRNCwV0%3D" alt="Don’t Censor Me!" /></p>
<p>Via <a href="http://pablojimeno.tumblr.com/post/16456731207/dont-censor-me">Pablo Jimeno</a></p>
]]></content:encoded>
		</item>
		<item>
		<title>xailer.info (esp): Error.log</title>
		<link>http://xailer.info/esp/?p=794</link>
		<pubDate>Wed, 25 Jan 2012 20:03:42 +0000</pubDate>
		<dc:creator>José Lalín</dc:creator>
		
	<category>error log</category>
	<category>Plugin</category>
	<category>plugins</category>
	<category>Xailer 2.5</category>
		<guid>http://xailer.info/esp/?p=794</guid>
		<description><![CDATA[Cuando lanzamos una aplicación desde el IDE y aparece un error en tiempo de ejecución sucede que, por motivos que van desde el cansancio o la falta de concentración hasta directamente porque se ha producido un error no recuperable (recursión, GPF, etc.), se cierra la aplicación sin darnos tiempo a anotar en qué lugar del [...]]]></description>
			<content:encoded><![CDATA[<p>Cuando lanzamos una aplicación desde el IDE y aparece un error en tiempo de ejecución sucede que, por motivos que van desde el cansancio o la falta de concentración hasta directamente porque se ha producido un error no recuperable (recursión, GPF, etc.), se cierra la aplicación sin darnos tiempo a anotar en qué lugar del código estaba el error.</p>
<p><span id="more-794"></span><br />
<img class="alignnone size-full wp-image-796" title="ErrorLogError" src="http://xailer.info/esp/wp-content/uploads/2012/01/ErrorLogError.png" alt="ErrorLogError" width="600" height="139" /></p>
<p>Para evitar tener que reproducir otra vez cada uno de los pasos para llegar al error usaremos este plugin que añade una nueva opción al menú <em>Ver </em>del IDE que permite mostrar la información de error completa o resumida  así como borrar el archivo del disco cuando ya no es necesario.</p>
<p><img class="size-full wp-image-797 alignnone" title="ErrorLogMenu" src="http://xailer.info/esp/wp-content/uploads/2012/01/ErrorLogMenu.png" alt="ErrorLogMenu" width="396" height="331" /></p>
<p>Desde la <em>vista error.log</em> es posible copiar la información del error al portapapeles en el mismo formato en que se está mostrando, completa o resumida, para, por ejemplo, enviarla por correo:</p>
<p><img class="alignnone size-full wp-image-798" title="ErrorLogView" src="http://xailer.info/esp/wp-content/uploads/2012/01/ErrorLogView1.png" alt="ErrorLogView" width="747" height="186" /></p>
<p>El archivo para descargar: <a href="http://www.xailer.com/download?file=50">ErrorLog</a></p>
<p><span >El plugin sólo funciona con Xailer 2.5 y Xailer 2.5.1</span></p>
]]></content:encoded>
		</item>
		<item>
		<title>Picando Código: Disponible Oil Rush 1.00 :)</title>
		<link>http://feedproxy.google.com/~r/picandocodigo/~3/NA-n-H31PbE/</link>
		<pubDate>Wed, 25 Jan 2012 12:30:00 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
		
	<category>Videojuegos/Nintendo</category>
	<category>juegos gnu/linux</category>
	<category>Oil Rush</category>
		<guid>http://feedproxy.google.com/~r/picandocodigo/~3/NA-n-H31PbE/</guid>
		<description><![CDATA[El excelente juego de estrategia naval en tiempo real Oil [...]]]></description>
			<content:encoded><![CDATA[<div
id="attachment_5122" class="wp-caption alignright" style="width: 210px"><a
href="http://picandocodigo.net/wp-content/uploads/2011/06/oil-rush-box.png"><img
class="size-full wp-image-5122" title="Oil Rush" src="http://picandocodigo.net/wp-content/uploads/2011/06/oil-rush-box.png" alt="Oil Rush" width="200" height="319" /></a><p
class="wp-caption-text">Oil Rush</p></div><p>El excelente juego de estrategia naval en tiempo real <a
title="Oil Rush: Juego de estrategia en tiempo real multiplataforma" href="http://picandocodigo.net/2011/oil-rush-juego-de-estrategia-en-tiempo-real-multiplataforma/"><strong>Oil Rush</strong></a> (clic en el enlace para leer mi reseña) está disponible en su <strong>versión 1.00</strong>. Aquellos que lo preordenamos lo podemos descargar ya desde <a
href="https://store.unigine.com/accounts/files/">Unigine Online Store</a>.</p><p>Se está trabajando en versiones para Steam, Desura y Ubuntu Software. Éstas estarán disponibles en uno o dos días.</p><p>La versión 1.00 nos trae el tan esperado modo de campaña para un jugador. Pre ordené el juego en marzo del año pasado, y desde entonces he ido viendo cómo evoluciona poco a poco con cada nueva versión. Ahora me toca el turno de hacer la campaña y ver qué han estado preparando los desarrolladores para nosotros&#8230;</p><p>Es un juego bastante importante en lo que respecta al mundillo de videojuegos en plataformas GNU/Linux. Fue construido sobre el motor Unigine que da la oportunidad de realizar unos gráficos 3D impresionantes, corriendo de forma nativa en nuestro querido sistema.</p><p>Con suerte el juego tenga éxito, así lo espero. Esto abriría más el mercado de videojuegos en GNU/Linux, dándole la publicidad necesaria a su motor para que otras compañías lo tengan en cuenta a la hora de desarrollar sus juegos.</p><p>Ya estoy descargando esta nueva versión, y más tarde tendré la oportunidad de probarlo. Ahí les contaré qué me pareció. Mientras les dejo algunas fotos de versiones anteriores para que se hagan una idea de los excelentes gráficos del juego:</p><h3>Oil Rush 0.66</h3><div
class="ngg-galleryoverview" id="ngg-gallery-10-6173"><div
class="piclenselink"> <a
class="piclenselink" href="javascript:PicLensLite.start({feedUrl:'http://picandocodigo.net/wp-content/plugins/nextgen-gallery/xml/media-rss.php?gid=10&amp;mode=gallery'});"> [View with PicLens] </a></div><div
id="ngg-image-69" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-07.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-07" alt="oilrush-07" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-07.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-68" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-06.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-06" alt="oilrush-06" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-06.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-64" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-02.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-02" alt="oilrush-02" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-02.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-67" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-05.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-05" alt="oilrush-05" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-05.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-66" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-04.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-04" alt="oilrush-04" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-04.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-65" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-03.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-03" alt="oilrush-03" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-03.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-63" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-01.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-01" alt="oilrush-01" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-01.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-77" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-15.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-15" alt="oilrush-15" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-15.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-76" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-14.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-14" alt="oilrush-14" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-14.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-75" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-13.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-13" alt="oilrush-13" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-13.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-74" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-12.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-12" alt="oilrush-12" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-12.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-73" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-11.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-11" alt="oilrush-11" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-11.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-72" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-10.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-10" alt="oilrush-10" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-10.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-71" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-09.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-09" alt="oilrush-09" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-09.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-86" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-24.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-24" alt="oilrush-24" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-24.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-85" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-23.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-23" alt="oilrush-23" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-23.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-84" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-22.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-22" alt="oilrush-22" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-22.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-83" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-21.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-21" alt="oilrush-21" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-21.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-82" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-20.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-20" alt="oilrush-20" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-20.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-81" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-19.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-19" alt="oilrush-19" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-19.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-80" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-18.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-18" alt="oilrush-18" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-18.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-79" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-17.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-17" alt="oilrush-17" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-17.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-78" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-16.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-16" alt="oilrush-16" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-16.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-70" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-08.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-08" alt="oilrush-08" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-08.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-88" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-26.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-26" alt="oilrush-26" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-26.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-87" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush/oilrush-25.jpg" title=" " class="shutterset_set_10" > <img
title="oilrush-25" alt="oilrush-25" src="http://picandocodigo.net/wp-content/gallery/oil-rush/thumbs/thumbs_oilrush-25.jpg" width="100" height="75" /> </a></div></div><div
class="ngg-clear"></div></div><h3>Oil Rush 0.82</h3><div
class="ngg-galleryoverview" id="ngg-gallery-11-6173"><div
class="piclenselink"> <a
class="piclenselink" href="javascript:PicLensLite.start({feedUrl:'http://picandocodigo.net/wp-content/plugins/nextgen-gallery/xml/media-rss.php?gid=11&amp;mode=gallery'});"> [View with PicLens] </a></div><div
id="ngg-image-91" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/oil-rush-082-03.jpg" title=" " class="shutterset_set_11" > <img
title="oil-rush-082-03" alt="oil-rush-082-03" src="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/thumbs/thumbs_oil-rush-082-03.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-92" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/oil-rush-082-04.jpg" title=" " class="shutterset_set_11" > <img
title="oil-rush-082-04" alt="oil-rush-082-04" src="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/thumbs/thumbs_oil-rush-082-04.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-94" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/oil-rush-082-06.jpg" title=" " class="shutterset_set_11" > <img
title="oil-rush-082-06" alt="oil-rush-082-06" src="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/thumbs/thumbs_oil-rush-082-06.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-93" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/oil-rush-082-05.jpg" title=" " class="shutterset_set_11" > <img
title="oil-rush-082-05" alt="oil-rush-082-05" src="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/thumbs/thumbs_oil-rush-082-05.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-95" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/oil-rush-082-07.jpg" title=" " class="shutterset_set_11" > <img
title="oil-rush-082-07" alt="oil-rush-082-07" src="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/thumbs/thumbs_oil-rush-082-07.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-90" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/oil-rush-082-02.jpg" title=" " class="shutterset_set_11" > <img
title="oil-rush-082-02" alt="oil-rush-082-02" src="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/thumbs/thumbs_oil-rush-082-02.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-98" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/oil-rush-082-10.jpg" title=" " class="shutterset_set_11" > <img
title="oil-rush-082-10" alt="oil-rush-082-10" src="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/thumbs/thumbs_oil-rush-082-10.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-97" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/oil-rush-082-09.jpg" title=" " class="shutterset_set_11" > <img
title="oil-rush-082-09" alt="oil-rush-082-09" src="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/thumbs/thumbs_oil-rush-082-09.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-96" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/oil-rush-082-08.jpg" title=" " class="shutterset_set_11" > <img
title="oil-rush-082-08" alt="oil-rush-082-08" src="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/thumbs/thumbs_oil-rush-082-08.jpg" width="100" height="75" /> </a></div></div><div
id="ngg-image-89" class="ngg-gallery-thumbnail-box"  ><div
class="ngg-gallery-thumbnail" > <a
href="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/oil-rush-082-01.png" title=" " class="shutterset_set_11" > <img
title="oil-rush-082-01" alt="oil-rush-082-01" src="http://picandocodigo.net/wp-content/gallery/oil-rush-082-01/thumbs/thumbs_oil-rush-082-01.png" width="100" height="75" /> </a></div></div><div
class="ngg-clear"></div></div><p>&nbsp;</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/picandocodigo?a=NA-n-H31PbE:P4aK8Bp5oKk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/picandocodigo?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/picandocodigo?a=NA-n-H31PbE:P4aK8Bp5oKk:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/picandocodigo?i=NA-n-H31PbE:P4aK8Bp5oKk:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/picandocodigo?a=NA-n-H31PbE:P4aK8Bp5oKk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/picandocodigo?i=NA-n-H31PbE:P4aK8Bp5oKk:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/picandocodigo/~4/NA-n-H31PbE" height="1" width="1"/>]]></content:encoded>
		</item>
		<item>
		<title>Variable not found: Libro: Dependency injection in .NET</title>
		<link>http://feedproxy.google.com/~r/vnf/~3/ri35IjEnO_A/libro-dependency-injection-in-net.html</link>
		<pubDate>Wed, 25 Jan 2012 12:25:00 +0000</pubDate>
		<dc:creator>José M. Aguilar</dc:creator>
		
	<category>Libros</category>
	<category>patrones</category>
		<guid>http://feedproxy.google.com/~r/vnf/~3/ri35IjEnO_A/libro-dependency-injection-in-net.html</guid>
		<description><![CDATA[La inyección de dependencias es uno de esos conceptos rodeados de misterio que parecen reservados a gurús, arquitectos,&#160;y otros profesionales de gama alta, y aplicables exclusivamente en proyectos mastodóndicos.

Y nada más lejos de la realida...]]></description>
			<content:encoded><![CDATA[La inyección de dependencias es uno de esos conceptos rodeados de misterio que parecen reservados a gurús, arquitectos,&nbsp;y otros profesionales <em>de gama alta</em>, y aplicables exclusivamente en proyectos mastodóndicos.<br></br>
<br></br>
Y nada más lejos de la realidad: DI se basa en principios relativamente simples, e incluso diría intuitivos, para lograr evitar el acoplamiento entre componentes, es aplicable en todo tipo y tamaño de aplicaciones, y por tanto todas ellas pueden beneficiarse de las ventajas que aporta, como la simplicidad, mantenibilidad, extensibilidad, o facilidad para la realización de pruebas unitarias.<br></br>
<a name="more"></a><br></br>
<img align="right" alt="Dependency Injection in .NET. Manning." border="0" height="215" src="http://lh4.ggpht.com/-wJvQO65rEUg/TvnAD2bTtAI/AAAAAAAABtU/sf0YaZLUHHs/image4.png?imgmax=800"  title="Dependency Injection in .NET. Manning." width="171"></img>Pero, sinceramente, jamás pensé que el tema que pudiera dar tanto de sí como para escribir un libro. Por eso me ha sorprendido la lectura, por cortesía de <a href="http://auges.org/">Auges</a>, del libro “<a href="http://www.manning.com/seemann/">Dependency Injection in .NET</a>”, escrito por por <a href="http://blog.ploeh.dk/">Mark Seemann</a> y publicado por la editorial Manning, donde he podido comprobar que mis conocimientos sobre inyección de dependencias, aunque válidos, eran bastante superficiales.<br></br>
<br></br>
El libro se estructura en cuatro grandes bloques a través de los cuales se realiza un completo recorrido guiado por los conceptos, utilización y herramientas para aplicar DI:<br></br>
<ul>
<li><strong>“Putting Dependency Injection on the map”</strong> contiene tres capítulos introductorios, útiles para poner en contexto el patrón y las ventajas que conlleva su uso y describir los conceptos fundamentales utilizados: dependencias, tipos, tiempo de vida, intercepción, contenedores, y muchos otros.</li>
<li><strong>“DI catalog”</strong> es una completa relación de patrones de uso de la inyección de dependencias, antipatrones o malos usos que podemos hacer de la misma, y refactorizaciones que podemos utilizar para solucionar escenarios frecuentes.</li>
<li><strong>“DIY DI”</strong> describe técnicas asociadas a la ID, como la composición de objetos, la gestión del ciclo de vida, y la intercepción de llamadas.</li>
<li><strong>“DI containers”</strong> es un completo bloque donde se describe el uso de los principales contenedores disponibles para la plataforma .NET: Castle Windsor, StructureMap, Spring.NET, Autofac, Unity y MEF.</li>
</ul>
En definitiva, se trata una lectura recomendable para desarrolladores .NET, tanto para aquellos que no hayan tenido experiencia previa con la Inyección de Dependencias y anden buscando fórmulas para reducir el acoplamiento entre componentes, como para los que ya se han enfrentado a ella y desean conocer en mayor profundidad las bases que la sustentan.<br></br>
Como puntos negativos, que está disponible exclusivamente en inglés, y que algunos capítulos se hacen algo densos y requieren varias pasadas para poder asimilar las ideas transmitidas.<br></br>
<br></br>
Enlace: <a href="http://www.manning.com/seemann/" title="http://www.manning.com/seemann/">http://www.manning.com/seemann/</a><br></br>
<br></br>
Publicado en: <a href="http://www.variablenotfound.com/">Variable not found</a>.<div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/27752126-7918748243823975697?l=www.variablenotfound.com" alt=""></img></div>
<p><a href="http://feedads.g.doubleclick.net/~a/U5JP1iUNrROsi_wx452Ka0Cik_U/0/da"><img src="http://feedads.g.doubleclick.net/~a/U5JP1iUNrROsi_wx452Ka0Cik_U/0/di" border="0" ismap="true"></img></a><br></br>
<a href="http://feedads.g.doubleclick.net/~a/U5JP1iUNrROsi_wx452Ka0Cik_U/1/da"><img src="http://feedads.g.doubleclick.net/~a/U5JP1iUNrROsi_wx452Ka0Cik_U/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/vnf?a=ri35IjEnO_A:YkEvoOIe6ow:ecdYMiMMAMM"><img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=ri35IjEnO_A:YkEvoOIe6ow:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=ri35IjEnO_A:YkEvoOIe6ow:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=ri35IjEnO_A:YkEvoOIe6ow:4cEx4HpKnUU"><img src="http://feeds.feedburner.com/~ff/vnf?i=ri35IjEnO_A:YkEvoOIe6ow:4cEx4HpKnUU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=ri35IjEnO_A:YkEvoOIe6ow:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/vnf?i=ri35IjEnO_A:YkEvoOIe6ow:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=ri35IjEnO_A:YkEvoOIe6ow:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/vnf?i=ri35IjEnO_A:YkEvoOIe6ow:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=ri35IjEnO_A:YkEvoOIe6ow:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/vnf/~4/ri35IjEnO_A" height="1" width="1"></img>]]></content:encoded>
		</item>
		<item>
		<title>Arragonán: Taller Spring I/O 2012: Modulariza tus aplicaciones Grails</title>
		<link>http://feedproxy.google.com/~r/danilat/~3/PT-31faq8Vk/</link>
		<pubDate>Wed, 25 Jan 2012 00:48:22 +0000</pubDate>
		<dc:creator>Dani</dc:creator>
		
	<category>grails</category>
	<category>Groovy</category>
		<guid>http://feedproxy.google.com/~r/danilat/~3/PT-31faq8Vk/</guid>
		<description><![CDATA[Este año volveré a estar por el Spring I/O (16 y 17 de Febrero 2012 en Madrid), en esta ocasión dirigiendo el taller Modulariza tus aplicaciones Grails : Gracias a los plugins de grails liberados a la comunidad, podemos aprovechar el esfuerzo hecho por otros desarrolladores y reutilizar el trabajo que han hecho. El sistema [...]]]></description>
			<content:encoded><![CDATA[<p>Este año volveré a estar por el <a href="http://www.springio.net/">Spring I/O</a> (16 y 17 de Febrero 2012 en Madrid), en esta ocasión dirigiendo el taller <strong>Modulariza tus aplicaciones Grails </strong>: </p>
<blockquote><p>Gracias a los plugins de grails liberados a la comunidad, podemos aprovechar el esfuerzo hecho por otros desarrolladores y reutilizar el trabajo que han hecho. El sistema de plugins de grails da múltiples puntos de extensión para la plataforma: permite añadir comandos nuevos a la CLI, servicios, clases de dominio, extender dinámicamente algunos comportamientos&#8230; En el taller sacaremos partido del sistema de plugins de grails para reutilizar trabajo entre distintas de nuestras aplicaciones, veremos algunos ejemplos y desarrollaremos un plugin a modo de ejemplo.</p></blockquote>
<div ><img src="http://springio.net/images/speaker_badge_springio_2012.png" alt="" /></div>
<p>Básicamente, mostraremos de forma práctica como reutilizar código en nuestros proyectos del día a día, más allá de liberar plugins que sólo tengan sentido ser liberados para el resto de la comunidad.</p>
<p>Este año volverán a ser 2 días de charlas y talleres, un eventazo a <a href="http://www.springio.net/register">un precio de risa</a>. Como podéis ver <a href="http://www.springio.net/agenda">en la agenda</a>, hay buena cantidad y calidad de ponentes, incluida alguna <strong>rockstar</strong> internacional entre ellos.</p>
<p>Cualquiera que trabaje o le interesen tecnologías alrededor de los ecosistemas <em>Spring</em>, <em>Grails</em> o <em>Groovy</em> debería asistir a este evento; o también a quienes les interesan cosas relacionadas con <em>Mongodb</em>, <em>Scala</em>, <em>ElasticSearch</em>, <em>RabbitMQ</em> o incluso temas de <em>cloud computing</em>.</p>
<p>Pero seguro que lo mejor está por los pasillos, durante los cafés y las comidas&#8230; o, por descontado, en la <strong>fiestaca</strong> del jueves <img src='http://www.danilat.com/weblog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p><strong>Nos vemos en el Spring I/O!</strong></p>
]]></content:encoded>
		</item>
		<item>
		<title>Variable not found: SignalR (II): Conexiones persistentes</title>
		<link>http://feedproxy.google.com/~r/vnf/~3/CJXxK_fjlTE/signalr-ii-conexiones-persistentes.html</link>
		<pubDate>Tue, 24 Jan 2012 08:14:00 +0000</pubDate>
		<dc:creator>José M. Aguilar</dc:creator>
		
	<category>Desarrollo</category>
	<category>ASP.NET</category>
	<category>aspnetmvc</category>
	<category>signalr</category>
		<guid>http://feedproxy.google.com/~r/vnf/~3/CJXxK_fjlTE/signalr-ii-conexiones-persistentes.html</guid>
		<description><![CDATA[Hace poco estuvimos viendo por aquí conceptos básicos sobre SignalR, el componente que nos permite crear espectaculares aplicaciones en las que múltiples usuarios pueden estar colaborando de forma simultánea, asíncrona, y en tiempo real. 

Entre o...]]></description>
			<content:encoded><![CDATA[Hace poco estuvimos viendo por aquí <a href="http://www.variablenotfound.com/2012/01/introduccion-signalr-i-conceptos.html">conceptos básicos sobre SignalR</a>, el componente que nos permite crear espectaculares aplicaciones en las que múltiples usuarios pueden estar colaborando <strong>de forma simultánea, asíncrona, y en tiempo real</strong>. <br></br>
<br></br>
Entre otras cosas, comentábamos que SignalR&nbsp; crea una capa de abstracciones sobre una conexión virtual permanente entre cliente y servidor, sobre la que podemos trabajar de diferentes formas:<br></br>
<ul>
<li>mediante <strong>conexiones persistentes</strong>, la opción de menor nivel, que proporciona mecanismos de notificación de conexión y desconexión de clientes, así como para recibir y enviar mensajes asíncronos a clientes conectados, tanto de forma individual como colectiva. </li>
<li>mediante el uso de <strong>“hubs”</strong>, que ofrece una interfaz de desarrollo mucho más sencilla, con una integración entre cliente y servidor que parece pura magia, y que seguro será la opción más utilizada por su potencia y facilidad de uso. </li>
</ul>
En este post estudiaremos la primera opción, <strong>conexiones persistentes</strong>. Los hubs los veremos en un artículo posterior de la serie, aunque si sois impacientes ya podéis ir leyendo el fantástico post del amigo Marc Rubiño sobre el tema, “<a href="http://mrubino.net/2012/01/17/push-con-singalr/">Push con SignalR</a>”.<br></br>
<br></br>
<a name="more"></a><img align="right" alt="Demo de conexiones persistentes" border="0" height="329" src="http://lh3.ggpht.com/-qRgGWyleqvE/Txxa9_J3MtI/AAAAAAAABvU/5kLBDXUgIJU/image4.png?imgmax=800"  title="Demo de conexiones persistentes" width="365"></img>Bueno, pues vamos al tema: emplearemos esta vía para implementar una funcionalidad bastante simple, pero nada trivial utilizando las herramientas habituales de ASP.NET: mostrar en una página, en tiempo real, información sobre los usuarios que están llegando a ella, los que la abandonan y el número de usuarios que hay conectados justo en ese momento, en tiempo real. <br></br>
<br></br>
Para ello haremos lo siguiente:<br></br>
<ol>
<li>En el lado servidor, <strong>implementaremos un servicio (endpoint) SignalR</strong>, que es el que procesará las conexiones y desconexiones de clientes, y enviará información actualizada por las conexiones abiertas. </li>
<li><strong>Registraremos este endpoint durante la inicialización</strong> de la aplicación, asociándole una URL de acceso a las funcionalidades del servicio. </li>
<li><strong>En el lado cliente implementaremos la conexión con el servicio</strong>, capturaremos la información que nos vaya enviando y la mostraremos en la página en forma de log. </li>
</ol>
El resultado lucirá tal y como se muestra en la captura de pantalla adjunta. Aunque si lo preferís, podéis verlo en vivo y en directo descargando y ejecutando el proyecto de demostración que encontraréis al final de este artículo.<br></br>
<br></br>
Ya en el post anterior de la serie vimos cómo <a href="http://www.variablenotfound.com/2012/01/introduccion-signalr-i-conceptos.html">descargar e instalar SignalR en un proyecto</a>, así que vamos a suponer que ese paso ya lo hemos realizado previamente.<br></br>
<h3>



1. Implementación del endpoint</h3>
El endpoint, o servicio SignalR, que vamos a implementar utilizando el enfoque de conexión persistente es simplemente una clase que hereda de <code>SignalR.PersistentConnection</code>, en la que podemos sobrescribir los métodos que necesitemos para implementar nuestras funcionalidades. En ella encontramos métodos como <code>OnConnected()</code>, <code>OnDisconnect()</code>, <code>OnReceived()</code>, y bastantes más, que nos permiten tomar el control cuando se producen determinados eventos de interés en la conexión:<br></br>
<pre ><span ><span >&nbsp;&nbsp;&nbsp; <span >public</span>&nbsp;<span >class</span>&nbsp;<span >VisitorsService</span> : <span >PersistentConnection</span>
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >protected</span>&nbsp;<span >override</span>&nbsp;<span >void</span>&nbsp; OnConnected(<span >HttpContextBase</span> context, <span >string</span> clientId) { ... }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >protected</span>&nbsp;<span >override</span>&nbsp;<span >void</span>&nbsp; OnDisconnect(<span >string</span> clientId) { ... }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >protected</span>&nbsp;<span >override</span>&nbsp;<span >void</span>&nbsp; OnReceived(<span >string</span> clientId, <span >string</span> data) { ... }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >// [...]</span>
&nbsp;&nbsp;&nbsp; }</span></span></pre>
Observad que el interfaz es bastante similar a la que encontramos al trabajar directamente con sockets: podemos introducir lógica cuando un nuevo cliente se conecte sobrescribiendo el método <code>OnConnected()</code>,&nbsp; cuando se desconecte, haciendo lo propio con <code>OnDisconnect()</code>, o cuando el cliente envíe algún tipo de mensaje al servidor, que ejecutará la funcionalidad implementada en <code>OnReceived()</code>.<br></br>
<br></br>
De la misma forma, la clase base <code>PersistentConnection</code> ofrece mecanismos para <strong>enviar mensajes directos a un cliente, a grupos de ellos, o a todos los clientes conectados</strong>.<br></br>
<br></br>
Volviendo al sistema que estamos desarrollando, básicamente para alcanzar nuestros objetivos necesitamos:<br></br>
<ul>
<li>tomar el control en el momento en que se produce una nueva conexión (método <code>OnConnected</code>), momento en que enviaremos al resto de clientes un mensaje con información sobre el cliente conectado y el total de conexiones activas. </li>
<li>tomar el control en el momento en que se produce la desconexión de un cliente (método <code>OnDisconnect()</code>), para notificar al resto y actualizarles el número de clientes conectados. </li>
</ul>
<h4>



1.1. Notificando a los clientes las nuevas conexiones </h4>
Cuando se realiza una nueva conexión al servicio, es decir, la llegada de un nuevo cliente, SignalR invocará al método <code>OnConnected()</code> del <em>endpoint</em> suministrándole el contexto de la petición HTTP actual, y un “ClientId”. El primero nos puede ser muy interesante para <strong>acceder a información de la petición</strong> (como el navegador, IP, cookies, información de autenticación, etc.), y el segundo es un <strong>identificador único generado por SignalR</strong> para realizar el seguimiento de la conexión.<br></br>
<br></br>
Implementamos nuestro método y lo comentamos justo a continuación:<br></br>
<pre ><span ><span >&nbsp;&nbsp;&nbsp; <span >protected</span>&nbsp;<span >override</span>&nbsp;<span >void</span> OnConnected(<span >HttpContextBase</span> context, <span >string</span> clientId)
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >var</span> clientDescription = getClientDescription(context);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _clients.TryAdd(clientId, clientDescription);
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >string</span> text = clientDescription + <span >" arrived."</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >var</span> msg = <span >new</span>&nbsp;<span >NotificationMessage</span>(text, _clients.Count);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Connection.Broadcast(msg);
&nbsp;&nbsp;&nbsp; }</span></span></pre>
Lo primero que hacemos en la implementación del método es obtener una descripción textual del cliente (que puede ser el nombre del usuario autenticado, o su IP), utilizando el método <code>getClientDescription()</code>, que veremos más adelante. Esta descripción, asociada al ClientId, es almacenada en el diccionario estático <code>_clients</code>, lo que nos permitirá conocer en todo momento los clientes conectados.<br></br>
<br></br>
Justo después componemos el mensaje y realizamos el envío a todos los usuarios conectados invocando el método <code>Broadcast()</code> de la propiedad de instancia <code>Connection</code>, que nos da acceso al canal virtual abierto entre clientes y servidor. El parámetro que recibe este método es de tipo <code>object</code>, y viajará serializado en formato JSON hasta cada uno de los clientes conectados; en este caso, hemos creado una clase llamada <code>NotificationMessage</code> que contiene toda la información que necesitamos suministrarles:<br></br>
<pre ><span ><span ><span >public</span></span><span >&nbsp;<span >class</span>&nbsp;<span >NotificationMessage</span>
{
&nbsp;&nbsp;&nbsp; <span >public</span> NotificationMessage(<span >string</span> message, <span >int</span> onlineUsers)
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OnlineUsers = onlineUsers;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Message = message;
&nbsp;&nbsp;&nbsp; }
 
&nbsp;&nbsp;&nbsp; <span >public</span>&nbsp;<span >string</span> Date
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >get</span> { <span >return</span> System.<span >DateTime</span>.Now.ToLongTimeString(); }
&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp; <span >public</span>&nbsp;<span >string</span> Message { <span >get</span>; <span >set</span>; }
&nbsp;&nbsp;&nbsp; <span >public</span>&nbsp;<span >int</span> OnlineUsers { <span >get</span>; <span >set</span>; }
}</span></span></pre>
Es conveniente tener en cuenta, sin embargo, que es posible enviar cualquier tipo de objeto: tipos propios (como en el ejemplo anterior), objetos anónimos, primitivos, o lo que se nos ocurra. Simplemente será serializado como JSON y llegará al cliente de forma directa (más adelante veremos cómo).<br></br>
<br></br>
Los miembros auxiliares utilizados en el código anterior son los siguientes:<br></br>
<pre ><span ><span >&nbsp;&nbsp;&nbsp; <span >private</span>&nbsp;<span >static</span>&nbsp;<span >ConcurrentDictionary</span>&lt;<span >string</span>, <span >string</span>&gt; _clients =
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >new</span>&nbsp;<span >ConcurrentDictionary</span>&lt;<span >string</span>, <span >string</span>&gt;();
 
&nbsp;&nbsp;&nbsp; <span >private</span>&nbsp;<span >static</span>&nbsp;<span >string</span> getClientDescription(<span >HttpContextBase</span> context)
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >var</span> browser = context.Request.Browser.Browser + <span >" "</span> +
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; context.Request.Browser.Version;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >var</span> name = context.Request.IsAuthenticated ?
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >"User "</span> + context.User.Identity.Name :
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >"IP "</span> + context.Request.UserHostAddress;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >return</span> name + <span >" ("</span> + browser + <span >")"</span>;
&nbsp;&nbsp;&nbsp; }</span></span></pre>
Observad que el diccionario donde almacenamos la información sobre las conexiones ha sido definido como <code>ConcurrentDictionary</code> para evitar problemas de concurrencia durante las actualizaciones, y es estático para que su información sea compartida entre todas las instancias del servicio.<br></br>
<h4>



1.2. Notificando a los clientes las desconexiones </h4>
Cuando SignalR detecta que un cliente se ha desconectado, invocará al método virtual <code>OnDisconnect()</code> del <em>endpoint</em>, lo cual nos permite introducir lógica de gestión del evento. En nuestro caso, simplemente necesitamos eliminar al cliente del diccionario donde los estamos almacenando, <br></br>
<br></br>
De la misma forma, debemos controlar las desconexiones para notificar este hecho a los clientes aún conectados, para lo que sobrescribimos el método <code>OnDisconnect()</code>:<br></br>
<pre ><span ><span >&nbsp;&nbsp;&nbsp; <span >protected</span>&nbsp;<span >override</span>&nbsp;<span >void</span> OnDisconnect(<span >string</span> clientId)
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >string</span> text, clientDescription;
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >if</span> (_clients.TryRemove(clientId, <span >out</span> clientDescription))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; text = clientDescription + <span >" is leaving."</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >else</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; text = <span >"Unknown user leaving."</span>;
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >var</span> msg = <span >new</span>&nbsp;<span >NotificationMessage</span>(text, _clients.Count);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Connection.Broadcast(msg);
&nbsp;&nbsp;&nbsp; }</span></span></pre>
En este método recibimos el ClientId que SignalR asignó al cliente en el momento de iniciar la conexión; lo único que hacemos es buscarlo en el diccionario de clientes donde los estamos almacenando, eliminarlo, y enviar un mensaje broadcast al resto de usuarios indicando la desconexión que se ha producido.<br></br>
<br></br>
Cuando implementéis funcionalidades en la desconexión, tened en cuenta que <strong>SignalR tarda unos segundos en darse cuenta de las desconexiones</strong> (recordad que con el transporte utilizado por defecto se trata de una conexión persistente virtual) por lo que puede aparecer un leve retraso en las notificaciones. Estos tiempos, en cualquier caso, pueden ser configurados (en el proyecto de demostración podéis ver cómo hacerlo).<br></br>
<br></br>
<strong>[Actualización]</strong>: como bien indica Arturo en un comentario del post, <strong>para que las desconexiones sean notificadas correctamente es necesario utilizar IIS o IIS Express</strong>. Con Cassini (el servidor web integrado en VS) no funcionará bien este mecanismo.<br></br>
<h4 id="observaciones">



1.3. Algunas observaciones adicionales</h4>
Al principio de comenzar a jugar con conexiones persistentes de SignalR, una de las cosas que pueden llamar la atención es que si en la implementación del método <code>OnConnected()</code> enviamos un broadcast a todos los usuarios conectados,&nbsp; el usuario actual (el que ha provocado la llamada a <code>OnConnected</code>) no recibirá el mensaje; o en otras palabras, <strong>el broadcast llegará a todos los clientes excepto al que acaba de realizar la conexión</strong>.<br></br>
<br></br>
Desconozco si se trata de un comportamiento por diseño, si es algo que se modificará en posteriores revisiones de SignalR (recordemos que en estos momentos es todavía una versión preliminar), o si simplemente se trata de un nombre para el método poco afortunado, pues en mi opinión da a entender que la conexión ya ha sido realizada y, por tanto, el broadcast debería llegarle también.<br></br>
<br></br>
Pero en cualquier caso, en la implementación del proyecto de pruebas que podéis descargar al final de este post veréis cómo lo he solucionado incluyendo una llamada explícita (“ping”) desde el cliente al servidor para forzar el envío de un mensaje de actualización justo después de completarse la conexión. Conceptualmente, lo que se hace es:<br></br>
<ul>
<li>desde el cliente, una vez se ha realizado la conexión, realizar un envío de datos al servidor, algo similar a un “ping”, </li>
<li>en el método <code>OnReceived()</code> del servidor, capturar el mensaje enviado desde el cliente y responderle de forma directa con la información que nos interese hacerle llegar, que podría ser un mensaje de bienvenida y, como en otras ocasiones, el número de usuarios conectados:&nbsp;<pre ><span ><span >&nbsp;&nbsp;&nbsp; <span >protected</span>&nbsp;<span >override</span>&nbsp;<span >void</span> OnReceived(<span >string</span> clientId, <span >string</span> data)
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >var</span> msg = <span >new</span>&nbsp;<span >NotificationMessage</span>(<span >"Hi!"</span>, _clients.Count);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Send(clientId, msg);
&nbsp;&nbsp;&nbsp; }</span></span></pre>
</li>
</ul>
Más adelante, cuando tratemos la parte cliente del servicio, veremos cómo está implementado el envío desde el cliente de este “ping”.<br></br>
<h3>



2. Registro de ruta</h3>
<strong>Una vez tenemos el servicio implementado, debemos registrar en el sistema de routing</strong> de ASP.NET una URL a través de la cual será posible acceder al mismo. El lugar idóneo para hacerlo, como siempre que se trata de cargar la tabla de rutas, es en el global.asax, para que se ejecute durante la inicialización de la aplicación.<br></br>
<br></br>
Por ejemplo, en una aplicación ASP.NET MVC podría ser algo así:<br></br>
<pre ><span ><span >&nbsp;&nbsp;&nbsp; <span >public</span>&nbsp;<span >static</span>&nbsp;<span >void</span> RegisterSignalrConnections(<span >RouteCollection</span> routes)
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; routes.MapConnection&lt;<span >VisitorsService</span>&gt;(<span >"Visitors"</span>, <span >"VisitorsService/{*operation}"</span>);
&nbsp;&nbsp;&nbsp; }
 
&nbsp;&nbsp;&nbsp; <span >protected</span>&nbsp;<span >void</span> Application_Start()
&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RegisterSignalrConnections(<span >RouteTable</span>.Routes);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [...]
&nbsp;&nbsp;&nbsp; }</span></span></pre>
Observad que lo único que estamos haciendo es añadir a la tabla de rutas una entrada en la que asociamos el servicio, en este caso nuestra clase <code>VisitorsService</code>, a la dirección “<code>VisitorsService/{*operation}</code>”, que será la URL de acceso al mismo. <br></br>
<br></br>
El primer parámetro que enviamos al método <code>MapConnection()</code> es simplemente el nombre de la entrada en la tabla de rutas, no tiene demasiada importancia.<br></br>
<h3>



3. Implementación del cliente web</h3>
La implementación de clientes web para las conexiones persistentes desarrolladas con SignalR es bastante simple, y comienza incluyendo en la página o vista una <strong>referencia hacia la biblioteca cliente</strong> de este componente:<br></br>
<pre ><span ><span ><span >&lt;</span><span >script</span>&nbsp;<span >src</span><span >="</span><span ><span >@</span></span><span >Url.Content(</span><span >"~/Scripts/jquery.signalR.js"</span><span >)"</span>&nbsp;<span >type</span><span >="text/javascript"&gt;&lt;/</span><span >script</span></span><span >&gt;</span></span></pre>
Como siempre, esta inclusión puede realizarse a nivel de página, o bien en la Master o Layout si queremos aplicarlo a todas las vistas del sistema.<br></br>
<blockquote>
Nota: si queremos dar soporte a clientes antiguos que no soportan deserialización&nbsp;JSON de forma nativa (por ejemplo, IE7), será necesario descargar desde Nuget la biblioteca de scripts json2.js y referenciarla en la página antes de la carga de SignalR.js. En caso contrario, se lanzará una excepción con el error:<br></br>
<br></br>
“SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE&lt;8”&nbsp;</blockquote>
Centrándonos en nuestra aplicación, el marcado HTML será tan simple como el que se muestra a continuación, lo único que hacemos es dejar un “hueco” en el que introduciremos los mensajes que se vayan recibiendo del servidor:<br></br>
<pre ><span ><span ><span >&lt;</span></span><span ><span >h2</span><span >&gt;</span>Log<span >&lt;/</span><span >h2</span></span></span><span ><span ><span >&gt;
&lt;</span><span >div</span>&nbsp;<span >id</span><span >="log"&gt;&lt;/</span><span >div</span></span><span >&gt;</span></span></pre>
A continuación, necesitamos implementar el código de script que realice las siguientes tareas:<br></br>
<ul>
<li><strong>iniciar la conexión</strong> con el endpoint, </li>
<li>tras ello, <strong>enviar un “ping”</strong> para recibir el mensaje de bienvenida (recordad lo que os <a href="http://www.blogger.com/blogger.g?blogID=27752126#observaciones">comentaba previamente</a> de que el broadcast no se recibe por el cliente que inicia la conexión), </li>
<li>mostrar en el log la información recibida del servidor.</li>
</ul>
Y el código de script tampoco puede ser más sencillo:<br></br>
<pre ><span ><span ><span >&lt;</span></span><span ><span >script</span>&nbsp;<span >type</span><span >="text/javascript"&gt;</span>
&nbsp;&nbsp;&nbsp; $(<span >function</span> () {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >var</span> conn = $.connection(<span >"VisitorsService"</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conn.received(<span >function</span> (data) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span >var</span> text = data.Date + <span >" - "</span> + data.Message + <span >" "</span> +
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data.OnlineUsers + <span >" users online."</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $(<span >'#log'</span>).prepend(<span >"&lt;div&gt;"</span> + text + <span >"&lt;/div&gt;"</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conn.start(<span >function</span> () {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conn.send(<span >"ping"</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });
&nbsp;&nbsp;&nbsp; });
<span >&lt;/</span><span >script</span></span><span >&gt;</span></span></pre>
Lo comentamos muy rápidamente:<br></br>
<ul>
<li>en la variable <code>conn</code> obtenemos una referencia hacia el <em>endpoint</em>, identificado por el nombre de la conexión persistente, en este caso, <code>VisitorsService</code>. </li>
<li>sobre ella, definimos la función <code>received()</code>, que será invocada cuando el servidor envíe información. El parámetro que recibe la función anónima es la información enviada desde el servidor, que, recordaréis, en este caso se trataba en objetos de tipo <code>NotificationMessage</code>. Dado que la serialización y deserialización se realizan de forma automática, podemos acceder directamente a sus miembros, como podéis ver en el código para montar el mensaje e introducirlo en el log. </li>
<li>por último, iniciamos la conexión invocando al método <code>start()</code> de la conexión. Observad que este método admite un callback que será llamado cuando la conexión se haya establecido, momento que aprovechamos para enviar el “ping” al servidor que nos permitirá recibir el mensaje de bienvenida.</li>
</ul>
Y ¡esto es todo! <br></br>
<br></br>
Si tenéis un ratillo, no dejéis de descargar el proyecto de prueba y jugar un rato con él. Y sobre todo, observad las pocas líneas de código que hemos tenido que emplear para resolver esta funcionalidad y comparadlo con lo que supondría implementarla de forma artesana, con las técnicas tradicionales.<br></br>
<a href="https://skydrive.live.com/redir.aspx?cid=c3a43a99b617d787&amp;resid=C3A43A99B617D787!280&amp;parid=C3A43A99B617D787!279&amp;authkey=!APhkeh3_sBUH3nk">Descargar proyecto de prueba</a>.<br></br>
<br></br>
<strong>En el próximo post de la serie veremos cómo utilizar los Hubs</strong> de SignalR, un planteamiento con una abstracción aún mayor sobre la conexión y una integración entre cliente y servidor simplemente espectacular.<br></br>
<br></br>
Publicado en <a href="http://www.variablenotfound.com/">Variable not found</a>.<div class="blogger-post-footer"><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/27752126-3328613755633940093?l=www.variablenotfound.com" alt=""></img></div>
<p><a href="http://feedads.g.doubleclick.net/~a/2u8zdpQ8QhoBuJBAso4zUWYd8Is/0/da"><img src="http://feedads.g.doubleclick.net/~a/2u8zdpQ8QhoBuJBAso4zUWYd8Is/0/di" border="0" ismap="true"></img></a><br></br>
<a href="http://feedads.g.doubleclick.net/~a/2u8zdpQ8QhoBuJBAso4zUWYd8Is/1/da"><img src="http://feedads.g.doubleclick.net/~a/2u8zdpQ8QhoBuJBAso4zUWYd8Is/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/vnf?a=CJXxK_fjlTE:zT4Qx0M00AQ:ecdYMiMMAMM"><img src="http://feeds.feedburner.com/~ff/vnf?d=ecdYMiMMAMM" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=CJXxK_fjlTE:zT4Qx0M00AQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/vnf?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=CJXxK_fjlTE:zT4Qx0M00AQ:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/vnf?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=CJXxK_fjlTE:zT4Qx0M00AQ:4cEx4HpKnUU"><img src="http://feeds.feedburner.com/~ff/vnf?i=CJXxK_fjlTE:zT4Qx0M00AQ:4cEx4HpKnUU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=CJXxK_fjlTE:zT4Qx0M00AQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/vnf?i=CJXxK_fjlTE:zT4Qx0M00AQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=CJXxK_fjlTE:zT4Qx0M00AQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/vnf?i=CJXxK_fjlTE:zT4Qx0M00AQ:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/vnf?a=CJXxK_fjlTE:zT4Qx0M00AQ:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/vnf?d=I9og5sOYxJI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/vnf/~4/CJXxK_fjlTE" height="1" width="1"></img>]]></content:encoded>
		</item>
		<item>
		<title>Najaraba.com: Software libre, metodologías ágiles y más.: Nueva etapa profesional: la inspiración</title>
		<link>http://najaraba.blogspot.com/2012/01/nueva-etapa-profesional-la-inspiracion.html</link>
		<pubDate>Mon, 23 Jan 2012 08:25:00 +0000</pubDate>
		<dc:creator>Joserra</dc:creator>
		
	<category>personal</category>
	<category>trabajo</category>
	<category>organizacion</category>
	<category>Planeta Codigo</category>
	<category>Personas</category>
	<category>ágil</category>
		<guid>http://najaraba.blogspot.com/2012/01/nueva-etapa-profesional-la-inspiracion.html</guid>
		<description><![CDATA[No sería capaz de reflejar mejor estos últimos cinco años trabajando en Biko de cómo ya los ha reflejado Jessi en su blog.

Va de personas que son felices en su trabajo. Porque el desarrollo de  software no es trabajar con ordenadores y picar código. El desarrollo de  software es mucho más: son personas haciendo cosas grandes que  disfrutan con lo que hacen, y sobre todo, con quien lo hacen.
Este]]></description>
			<content:encoded><![CDATA[No sería capaz de reflejar mejor estos últimos cinco años trabajando en Biko de cómo ya los ha reflejado Jessi en su blog.

Va de personas que son felices en su trabajo. Porque el desarrollo de  software no es trabajar con ordenadores y picar código. El desarrollo de  software es mucho más: son personas haciendo cosas grandes que  disfrutan con lo que hacen, y sobre todo, con quien lo hacen.
Este]]></content:encoded>
		</item>
		<item>
		<title>Koalite's blog: Demasiada abstracción</title>
		<link>http://feedproxy.google.com/~r/KoalitesBlog/~3/NtN1GzyoolA/</link>
		<pubDate>Mon, 23 Jan 2012 03:47:04 +0000</pubDate>
		<dc:creator>Juanma</dc:creator>
		
	<category>NHibernate</category>
	<category>development</category>
	<category>queryover</category>
		<guid>http://feedproxy.google.com/~r/KoalitesBlog/~3/NtN1GzyoolA/</guid>
		<description><![CDATA[<script type="text/javascript">
				  (function() {
				    var po = document.createElement("script"); po.type = "text/javascript"; po.async = true;
				    po.src = "https://apis.google.com/js/plusone.js";
				    var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(po, s);
				  })();
				</script>Hay veces que llegamos a un punto en que intentamos abstraer demasiado las cosas y acabamos teniendo lo que se suele llamar una leaky abstraction. Se trata de casos en los cuales el mecanismo de abstracción no es efectivo, aquello que queremos abstraer acaba traspasando la capa de abstración y lo único que conseguimos es [...]
No hay posts relacionados.]]></description>
			<content:encoded><![CDATA[<p>Hay veces que llegamos a un punto en que intentamos abstraer demasiado las cosas y acabamos teniendo lo que se suele llamar una <a href="http://es.wikipedia.org/wiki/Leaky_abstraction" >leaky abstraction</a>. Se trata de casos en los cuales el mecanismo de abstracción no es efectivo, aquello que queremos abstraer acaba traspasando la capa de abstración y lo único que conseguimos es una complicación innecesaria.</p>
<p>Recientemente he padecido un caso claro de esto usando la API de consultas <code><a href="http://nhforge.org/blogs/nhibernate/archive/2009/12/17/queryover-in-nh-3-0.aspx" >QueryOver</a></code> de <a href="http://nhforge.org/Default.aspx" >NHibernate</a>. <code>QueryOver</code> está diseñado como una implementación del patrón <a href="http://martinfowler.com/eaaCatalog/queryObject.html" >Query Object</a> aprovechando expresiones lambda para hacer <a href="http://jagregory.com/writings/introduction-to-static-reflection/" >static reflection</a> y conseguir así que el API sea <em>type-safe</em> y <em>refactor friendly</em>. </p>
<p><code>QueryOver</code> intenta abstraer el acceso a la base datos, pero a la vez trata de mantener toda la potencia del SQL, por lo que en cuanto las consultas se complicando un poco acaba siendo un lío y la ganancia que tenemos por ser <em>type-safe</em> y <em>refactor friendly</em> no compensa la pérdida de legibilidad.</p>
<p>Veamos un ejemplo concreto bastante simpe. Supongamos que tenemos el típico modelo de clientes y pedidos y queremos lanzar una consulta para obtener el número de pedidos y el importe total pedido por cada cliente. La implementación con <code>QueryOver</code> es algo así:</p>
<pre class="brush:csharp">
Customer customer = null;
var stats = s.QueryOver<Order>()
    .JoinAlias(x => x.Customer, () => customer)
    .SelectList(lst => lst
                            .SelectGroup(() => customer.Id)
                            .SelectGroup(() => customer.Name)
                            .SelectSum(x => x.Total)
                            .SelectCount(x => x.Id))
    .List<object[]>();
</pre>
<p>El resultado es bastante feo. Para poder hacer el equivalente al <code>inner join</code> de forma <em>type-safe</em>, tenemos que declarar una variable de tipo <code>Customer</code> que usamos únicamente como alias para usarla luego en las expresiones lambda. Además, para construir la lista de columnas a devolver se usa un builder (<code>lst</code>) que simplifica un poco las cosas pero no acaba de resultar claro.</p>
<p>Si la misma consulta la lanzamos con el equivalente HQL, el lenguaje de consultas de NHibernate, tenemos:</p>
<pre class="brush:csharp">
var stats = s.CreateQuery(@"select c.Id, c.Name, sum(o.Total), count(o.Id)
                            from Order o right join o.Customer c
                            group by c.Id, c.Name")
             .List<object[]>();
</pre>
<p>Para cualquiera que esté acostumbrado a manejar SQL, está claro que la consulta resulta mucho más legible. Es cierto que no es <em>type-safe</em> no <em>refactor friendly</em>, pero en mi opinión la legibilidad lo compensa.</p>
<p>Parece que nuestra tendencia natural como desarrolladores es siempre abstraerlo todo, pero a veces hay que tener cuidado porque puede que estemos causando más problemas de los que solucionamos.</p>
<div class="trackable_sharing"><div class="trackable_sharing_text"><b><br/><br/><br/>Compartir enlace:
</b></div><a href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fblog.koalite.com%2F2012%2F01%2Fdemasiada-abstraccion%2F"  title="Facebook"  onclick="that=this;_gaq.push(['_trackEvent','SocialSharing','Facebook','http://blog.koalite.com/2012/01/demasiada-abstraccion/']); _trackableshare_window = window.open(this.href,'share','menubar=0,resizable=1,width=500,height=350'); _trackableshare_window.focus(); return false;"><img align="absmiddle" src="http://blog.koalite.com/wp-content/plugins/trackable-social-share-icons/buttons/f2//facebook.png" alt="Facebook" width="36" height="36"></a> <a href="http://twitter.com/share?url=http%3A%2F%2Fblog.koalite.com%2F2012%2F01%2Fdemasiada-abstraccion%2F&text=Demasiada+abstracci%C3%B3n"  title="Twitter"  onclick="that=this;_gaq.push(['_trackEvent','SocialSharing','Twitter','http://blog.koalite.com/2012/01/demasiada-abstraccion/']); _trackableshare_window = window.open(this.href,'share','menubar=0,resizable=1,width=500,height=350'); _trackableshare_window.focus(); return false;"><img align="absmiddle" src="http://blog.koalite.com/wp-content/plugins/trackable-social-share-icons/buttons/f2//twitter.png" alt="Twitter" width="36" height="36"></a> <a href="mailto:?subject=Check%20out%20http%3A%2F%2Fblog.koalite.com%2F2012%2F01%2Fdemasiada-abstraccion%2F"  title="Email" onclick="that=this;_gaq.push(['_trackEvent','SocialSharing','Email','http://blog.koalite.com/2012/01/demasiada-abstraccion/']); "><img align="absmiddle" src="http://blog.koalite.com/wp-content/plugins/trackable-social-share-icons/buttons/f2//email.png" alt="Email" width="36" height="36"></a> <br /><g:plusone annotation="none"></g:plusone></div><p>No hay posts relacionados.</p><img src="http://feeds.feedburner.com/~r/KoalitesBlog/~4/NtN1GzyoolA" height="1" width="1"/>]]></content:encoded>
		</item>
		<item>
		<title>Escuela De Codigo: GitHub, para el que empieza con Git</title>
		<link>http://escueladecodigo.com/github-para-el-que-empieza-con-git/</link>
		<pubDate>Mon, 23 Jan 2012 00:00:19 +0000</pubDate>
		<dc:creator>Hugo Gonzalez</dc:creator>
		
	<category>Tutoriales</category>
		<guid>http://escueladecodigo.com/github-para-el-que-empieza-con-git/</guid>
		<description><![CDATA[La semana pasada vimos una corta y puntual introducción a Git, solo lo necesario para el que no sabe nada de control de versiones deje de vivir en la era del oscurantismo y pase a ser parte del cada dia mas grande, grupo de iluminados que hacen de su vida de desarrollador mas facil, utilizando Git. Pues [...]]]></description>
			<content:encoded><![CDATA[<p ><a href="http://escueladecodigo.com/wp-content/uploads/2012/01/github-profile1.png"><img class="alignright  wp-image-1344" title="github-profile1" src="http://escueladecodigo.com/wp-content/uploads/2012/01/github-profile1.png" alt="" width="144" height="216" /></a>La semana pasada vimos una corta y puntual introducción a Git, solo lo necesario para el que no sabe nada de control de versiones deje de vivir en la era del oscurantismo y pase a ser parte del cada dia mas grande, grupo de iluminados que hacen de su vida de desarrollador mas facil, utilizando Git. Pues bien hoy en dia no se puede mencionar Git sin decir GitHub. ¿Que es? ¿Como se sirve? ¿Con que lo aderezo? En este articulo conoceremos GitHub y lo mucho que nos puede ayudar.<span id="more-1342"></span></p>
<h2 style="text-align: justify;">¿Que es GitHub?</h2>
<p ><div class="woo-sc-quote"><p>GitHub es un sitio web para alojar proyectos utilizando el sistema de control de versiones Git.</p></div></p>
<p >¿Necesitas alojar tu proyecto en algun repositorio Git que no sea en tu computadora? ¿No quieres perder tu tiempo configurando un servidor remoto como repositorio de Git? Entonces GitHub es para ti, un sitio web donde todos tus proyectos que utilicen Git estaran bien resguardados.</p>
<p >Seria muy injusto decir que GitHub solo es un simple sitio web para guardar repositorios Git. Porque la verdad es que es mucho mas que eso,<span class="shortcode-highlight">es una &#8220;red social&#8221; donde los desarrolladores compartimos nuestro codigo fuente con otros</span><!--/.shortcode-highlight-->. Todos los repositorios en GitHub son open source (todos los que no son de pago) asi que podemos descargarlos, clonarlos,enviar parches, corregir el codigo de otro, que otros nos envien sus cambios, etc, etc.</p>
<p >De esa forma no solo compartimos nuestro código, sino que lo exponemos a una audiencia de profesionales (como nosotros) para que lo puedan evaluar, corregir y mejorar <img src='http://escueladecodigo.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2 style="text-align: justify;">Para empezar, registrate en GitHub</h2>
<p>Ingresa a <a href="https://github.com/plans">https://github.com/plans</a> , elige el plan gratuito, llena el formulario (bastante simple no tendras problemas) y ya estas registrado!</p>
<p ><a href="http://escueladecodigo.com/wp-content/uploads/2012/01/Seleccin_004.png"><img class="aligncenter  wp-image-1358" title="Selección_004" src="http://escueladecodigo.com/wp-content/uploads/2012/01/Seleccin_004-1024x198.png" alt="" width="717" height="139" /></a></p>
<p ><a href="http://escueladecodigo.com/wp-content/uploads/2012/01/Seleccin_005.png"><img class="aligncenter  wp-image-1359" title="Selección_005" src="http://escueladecodigo.com/wp-content/uploads/2012/01/Seleccin_005.png" alt="" width="393" height="445" /></a></p>
<p ><a href="http://escueladecodigo.com/wp-content/uploads/2012/01/Seleccin_006.png"><img class="aligncenter  wp-image-1360" title="Selección_006" src="http://escueladecodigo.com/wp-content/uploads/2012/01/Seleccin_006.png" alt="" width="410" height="321" /></a></p>
<h2 style="text-align: left;">Mi primer repositorio</h2>
<p>Vamos a estrenarnos dentro de GitHub, para eso ya debemos tener correctamente configurado Git, ¿No lo has hecho?? <a title="Git, una guía básica para el que no sabe nada de control de versiones" href="http://escueladecodigo.com/git-una-guia-basica-para-el-que-no-sabe-nada-de-control-de-versiones/" >Tomate unos minutos para leer este articulo antes de continuar</a></p>
<h3>Crea un nuevo repositorio</h3>
<p><a href="http://escueladecodigo.com/wp-content/uploads/2012/01/Seleccin_007.png"><img class="aligncenter size-full wp-image-1366" title="Selección_007" src="http://escueladecodigo.com/wp-content/uploads/2012/01/Seleccin_007.png" alt="" width="421" height="140" /></a></p>
<p ><a href="http://escueladecodigo.com/wp-content/uploads/2012/01/Seleccin_009.png"><img class="aligncenter  wp-image-1368" title="Selección_009" src="http://escueladecodigo.com/wp-content/uploads/2012/01/Seleccin_009.png" alt="" width="497" height="375" /></a></p>
<p >GitHub es tan bueno con nosotros, que inmediatamente despues de crear el repositorio nos indica como debemos proceder, asi que hagamos lo que dice</p>
<p ><a href="http://escueladecodigo.com/wp-content/uploads/2012/01/Seleccin_010.png"><img class="aligncenter  wp-image-1372" title="Selección_010" src="http://escueladecodigo.com/wp-content/uploads/2012/01/Seleccin_010-1024x666.png" alt="" width="614" height="400" /></a></p>
<h3 style="text-align: left;">Sube el código</h3>
<p>Antes que nada, crea en tu computadora la carpeta donde tendras el código fuente, abre una terminal y escribe</p>
<pre class="terminal"><strong> mkdir Hola-Gato</strong></pre>
<p>y muevete dentro de la carpeta recien creada</p>
<pre class="terminal"><strong> cd Hola-Gato</strong></pre>
<p>inicializa el repositorio Git</p>
<pre class="terminal"><strong> git init</strong></pre>
<p >Los repositorios en GitHub tienen un archivo muy importante, el README, dentro de este archivo se colocan instrucciones que quieres que los desarrolladores lean desde que entran a ver tu repositorio, asi que no olvidemos crearlo. Utiliza <strong>Markdown</strong> para escribir en el.</p>
<pre class="terminal"><strong>touch README</strong></pre>
<p>Ahora que ya tienes un archivo en tu repositorio, lo agregamos</p>
<pre class="terminal"><strong>git add README</strong></pre>
<p>y ejecutamos nuestro primer commit</p>
<pre class="terminal"><strong>git commit -m &#8220;Primer commit en el proyecto&#8221;</strong></pre>
<p >Hasta este momento todo lo que hemos hecho, seria como cualquier proyecto en el que usemos Git, todo local, para relacionar nuestro código fuente con el repositorio remoto que recien hemos creado en GitHub debemos ejecutar lo siguiente</p>
<pre class="terminal"><strong>git remote add origin git@github.com:escueladecodigo/Hola-Gato.git</strong></pre>
<p>y finalmente subimos el codigo a GitHub</p>
<pre class="terminal"><strong>git push -u origin master</strong></pre>
<pre></pre>
<p >Ahora cuando demos en el enlace <strong>Continue </strong>veremos algo como lo siguiente</p>
<p ><a href="http://escueladecodigo.com/wp-content/uploads/2012/01/Seleccin_011.png"><img class="aligncenter  wp-image-1380" title="Selección_011" src="http://escueladecodigo.com/wp-content/uploads/2012/01/Seleccin_011-1024x640.png" alt="" width="614" height="384" /></a></p>
<p >Ahora ya tienes tu primer repositorio en GitHub, listo para que cualquiera lo vea, lo clone, haga forks, te envié mejoras, etc, etc. Solo llénalo un poco con tu código, no creo que un repositorio con un solo archivo README sea muy llamativo para otros desarrolladores <img src='http://escueladecodigo.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p >GitHub cuenta con tantas funcionalidades; resaltado de sintaxis, seguir desarrolladores, clonar repositorios, etc, etc. Por el momento dejare que tu curiosidad trabaje un poco y explores todo lo que Git junto con GitHub puede ofrecerte. En artículos posteriores iremos desglosando cada una de esas opciones, conociéndolas bien y sacandoles el máximo provecho posible. Así que no te pierdas los próximos artículos, te ayudaran no solo a conocer Git sino a usarlo como un ninja!</p>
]]></content:encoded>
		</item>
		<item>
		<title>xperiments.es: (English) i5hare project launched.</title>
		<link>http://xperiments.es/blog/es/i5hare-project-launched/</link>
		<pubDate>Sun, 22 Jan 2012 00:13:00 +0000</pubDate>
		<dc:creator>xperiments</dc:creator>
		
	<category>JavaScript</category>
	<category>JQuery</category>
	<category>HTML5</category>
		<guid>http://xperiments.es/blog/es/i5hare-project-launched/</guid>
		<description><![CDATA[Disculpa, pero esta entrada está disponible sólo en English.
]]></description>
			<content:encoded><![CDATA[<span class="read_later"><script type="text/javascript"><!--
			instapaper_embed( "http://xperiments.es/blog/es/i5hare-project-launched/", "(English) i5hare project launched.", "" );
		//--></script></span><p>Disculpa, pero esta entrada está disponible sólo en <a href="http://xperiments.es/blog/en/feed/atom/">English</a>.</p>
]]></content:encoded>
		</item>
		<item>
		<title>xperiments.es: (English) StageWebViewBridge Update</title>
		<link>http://xperiments.es/blog/es/stagewebviewbridge-update/</link>
		<pubDate>Sun, 22 Jan 2012 00:00:29 +0000</pubDate>
		<dc:creator>xperiments</dc:creator>
		
	<category>Flex</category>
	<category>as3</category>
	<category>Adobe AIR</category>
	<category>iOS</category>
		<guid>http://xperiments.es/blog/es/stagewebviewbridge-update/</guid>
		<description><![CDATA[Disculpa, pero esta entrada está disponible sólo en English.
]]></description>
			<content:encoded><![CDATA[<span class="read_later"><script type="text/javascript"><!--
			instapaper_embed( "http://xperiments.es/blog/es/stagewebviewbridge-update/", "(English) StageWebViewBridge Update", "" );
		//--></script></span><p>Disculpa, pero esta entrada está disponible sólo en <a href="http://xperiments.es/blog/en/feed/atom/">English</a>.</p>
]]></content:encoded>
		</item>
	</channel>
</rss>

