<?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/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>elBlëg - Interactividad, usabilidad y web</title>
	<atom:link href="http://www.elbleg.com/feed" rel="self" type="application/rss+xml" />
	<link>http://www.elbleg.com</link>
	<description>Interactividad, usabilidad y web</description>
	<lastBuildDate>Thu, 19 Aug 2010 16:41:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Evento Touch y animación para juegos básica con Objective-C</title>
		<link>http://www.elbleg.com/objective-c/evento-touch-y-animacio%cc%81n-para-juegos-ba%cc%81sica-con-objective-c.html</link>
		<comments>http://www.elbleg.com/objective-c/evento-touch-y-animacio%cc%81n-para-juegos-ba%cc%81sica-con-objective-c.html#comments</comments>
		<pubDate>Thu, 19 Aug 2010 09:16:06 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://www.elbleg.com/?p=312</guid>
		<description><![CDATA[Una de las acciones más comúnmente utilizadas en aplicaciones para iPhone o iPad es el evento “touch”.  Un evento no es útil si no activa una acción significativa. Acá vas a entender cómo agregar un evento touch a un botón y cómo activar la animación de un objeto. Al final, el resultado es este [...]]]></description>
			<content:encoded><![CDATA[<p>Una de las acciones más comúnmente utilizadas en aplicaciones para iPhone o iPad es el evento <em>“touch”</em>.  Un evento no es útil si no activa una acción significativa. Acá vas a entender cómo agregar un evento <em>touch</em> a un botón y cómo activar la animación de un objeto. <span id="more-312"></span>Al final, el resultado es este simple control de videojuego: </p>
<div class="imgbox">
<object id="scPlayer" class="embeddedObject" width="323" height="225" type="application/x-shockwave-flash" data="http://content.screencast.com/users/whoisyeco/folders/Jing/media/fcae0ef5-9169-439d-9f1c-b05147b699cc/jingswfplayer.swf" ><param name="movie" value="http://content.screencast.com/users/whoisyeco/folders/Jing/media/fcae0ef5-9169-439d-9f1c-b05147b699cc/jingswfplayer.swf" /><param name="quality" value="high" /><param name="bgcolor" value="#FFFFFF" /><param name="flashVars" value="thumb=http://content.screencast.com/users/whoisyeco/folders/Jing/media/fcae0ef5-9169-439d-9f1c-b05147b699cc/FirstFrame.jpg&#038;containerwidth=323&#038;containerheight=225&#038;content=http://content.screencast.com/users/whoisyeco/folders/Jing/media/fcae0ef5-9169-439d-9f1c-b05147b699cc/00000062.swf&#038;blurover=false" /><param name="allowFullScreen" value="true" /><param name="scale" value="showall" /><param name="allowScriptAccess" value="always" /><param name="base" value="http://content.screencast.com/users/whoisyeco/folders/Jing/media/fcae0ef5-9169-439d-9f1c-b05147b699cc/" /></object>
</div>
<p>Pero puede ser extendido ilimitadamente a lo que necesites.</p>
<h2>Paso 1: Crea un nuevo proyecto</h2>
<p>Abrí Xcode e inicia un nuevo proyecto, selecciona <em>“view based application”</em>, dale un nombre, yo le puse <em>“jumping”</em>, te recomiendo ponerle igual para que no te confundas luego.</p>
<div class="imgbox">
  <img src="http://elbleg.com/wp-content/uploads/2010/08/1-20100819-030241.jpg" />
</div>
<p><!-- # --></p>
<h2>Paso 2: Importa los recursos del proyecto</h2>
<p><strong><a href="http://elbleg.com/share/bleg_post_312.zip">Descargate este zip</a></strong>.  Ahí vas a encontrar todos las imágenes que vamos a necesitar para este proyecto, incluyendo tres sprites de Ryu de StreetFighter que me<strike> robé </strike>encontré en PanelMonkey. Vas a necesitar copiar esas imágenes al folder de recursos del proyecto arrastrándolos del finder al panel <em>“Groups &amp; Files”</em> en Xcode.</p>
<div class="imgbox"><img src="http://elbleg.com/wp-content/uploads/2010/08/2-20100819-030147.jpg"/> </div>
<p>Asegurate de seleccionar <em>“Copy items into destination group’s folder (if needed).”</em> cuando te salga la confirnación de Xcode.
</p>
<div class="imgbox">
<img src="http://elbleg.com/wp-content/uploads/2010/08/3-20100819-030326.jpg"/>
</div>
<p>Todas las imagenes que necesitás deberían quedar copiadas ahora en el mismo folder que contiene el proyecto. Ahora para mantener el folder de recursos ordenado, agrupa todas las imagenes que acabas de importar. Para hacerlo solo seleccionalas, click izquierdo y selecciona <em>“group”</em> en el menú que te aparece. Podés darle un nombre a ese grupo también, yo le puse al mío el originalísimo nombre de <em>“images”</em>. </p>
<div class="imgbox">
<img src="http://elbleg.com/wp-content/uploads/2010/08/4-20100819-024851.jpg" />
</div>
<p>Compila y ejecuta la aplicación tal y como está. No deben de haber errores de compilación y el simulador solo debe mostrar una pantalla gris. </p>
<h2>Paso 3: Modifica jumpingAppDelegate.m</h2>
<p>En jumpingAppDelegate.m, modifica el método applicationDidFinishLaunching agregando esta línea: </p>
<pre class="c" name="code">
// Asigna un nuevo view:  
self.viewController = [jumpingViewController alloc];  
  
[window addSubview:viewController.view]; 
</pre>
<p> <br />
Esto le va a asignar un nuevo view controller. Este paso es necesario porque no vas a usar Interface Builder para crear la vista por vos.</p>
<h2>Paso 4: Modifica jumpingViewController.h</h2>
<p>En el header del view controller (jumpingViewController.h), dentro del interface declará una nueva propiedad agregando:</p>
<pre class="c" name="code">
UIImageView *player;
</pre>
<p>  <br />
Luego agrega esto, antes de @end:</p>
<pre class="c" name="code">
@property (nonatomic, retain) UIImageView *player;
</pre>
<p>Esto te permite usar “player” como un class property para una imagen:<br />
El header debería verse algo así:</p>
<pre class="c" name="code">
#import <UIKit/UIKit.h>  
  
@interface jumpingViewController : UIViewController {  
    UIImageView *player;  
}  
  
@property (nonatomic, retain) UIImageView *player;  
  
@end  
</pre>
</p>
<h2>Paso 5: Modifica jumpingViewController.m</h2>
<p>Ahora te toca agregar los gráficos y los elementos de interfaz a esta vista<br />
Abre el archivo jumpingViewController.m y borra todos los métodos comentados que tenga. Dejá intactos los que no están comentados. </p>
<p>Al inicio, después de @implementation jumpingViewController, agregá:</p>
<pre class="c" name="code">  @synthesize player; </pre>
<p>Ahora actualiza el método dealloc para que quede así:</p>
<pre class="c" name="code">
- (void)dealloc {  
    [player release];  
    [super dealloc];  
} 
</pre>
<p>Ahora insertá este método:</p>
<pre class="c" name="code">
- (void)addButton {  
  
    UIButton *button = [[UIButton buttonWithType:UIButtonTypeCustom]  
                                         initWithFrame:CGRectMake(240, 150, 50, 50)];  
  
    // le da una imagen al botón  
    [button setBackgroundImage:[UIImage imageNamed:@"button.png"]  
                 forState:UIControlStateNormal];  
  
    // Fija un evento  
    [button addTarget:self action:@selector(buttonPressed)  
                 forControlEvents:UIControlEventTouchUpInside];  
  
    // Agrega el boton a la vista 
    [self.view addSubview:button];  
} 
</pre>
<p>El método addButton será llamado luego para&#8230; Sí… Eso… Añadir el botón a la vista.</p>
<p>La primer cosa a notar es que estás creando un botón custom. Lo segundo es que buttonPressed es el nombre de un método que va a ser llamado cuando el evento touch es ejecutado.</p>
<p>Create un método buttonPressed temporal agregando esto:</p>
<pre class="c" name="code">
- (void)buttonPressed {  
    NSLog(@"Botón presionado");  
}
</pre>
<p><code>NSLog()</code> enviará un mensaje a la consola, que dicho sea de paso podés ver en el menú Run (cmd + shift + R).<br />
Nuestro querido botón debe aparecer en la pantalla una vez que la vista ha cargado. Para hacer que eso pase agrega este método.</p>
<pre class="c" name="code">
- (void)loadView {  
  
    // Asigna la vista 
    self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];  
  
    // Establece el color de fondo de la vista 
    self.view.backgroundColor = [UIColor blackColor];  
  
    // Crea la imagen de fondo 
    UIImageView *bg = [[UIImageView alloc] initWithFrame:CGRectMake(0 , 0, 572, 206)];  
    [bg setImage:[UIImage imageNamed:@"bg.jpg"]];  
    [self.view addSubview:bg];  
  
    // Crea el botón  
    [self addButton];  
}  
</pre>
<p>Este método viene por defecto en los view controllers. Básicamente estás agregando una imagen de fondo y ejecutando el método addButton.</p>
<p>Ok. Guarda lo que has hecho, compila y ejecuta el proyecto. Deberías ver la imagen de fondo y un botón rojo. Si tenés la consola abierta debería desplegarse un mensaje de <code>NSLog()</code> al tocar el botón.</p>
<div class="imgbox">
<img src="http://elbleg.com/wp-content/uploads/2010/08/5-20100819-024954.jpg"/>
</div>
<h2>Paso 6:  Agregando un personaje a la pantalla</h2>
<p>Para inicializar el objeto <code>UIImageView</code>, añade lo siguiente en jumpingViewController.m antes del método addButton: </p>
<pre class="c" name="code">
- (void)initPlayer {  
    self.player = [[UIImageView alloc] initWithFrame:  
                   CGRectMake(10, 100, 77.0, 94.0)];  
    [self normalStance];  
    // opaco para un mejor performance  
    self.player.opaque = YES;  
    [self.view addSubview:self.player];  
}  
- (void)normalStance {  
    [self.player setImage:[UIImage imageNamed:@"ryu.png"]];  
}  
</pre>
<p>Ese código va a inicializar el <code>UIImageView</code> y agregarlo a la vista principal. El método <code>normalStance</code> te será útil luego.</p>
<p>Ahora vas a enviar el <code>initPlayer</code> a la vista principal, para hacerlo solo modificás el método <code>loadView</code> así:</p>
<pre class="c" name="code">
- (void)loadView {  
  
    // Asigna la vista 
    self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];  
  
    // Establece el color de fondo de la vista 
    self.view.backgroundColor = [UIColor blackColor];  
  
    // Crea la imagen de fondo 
    UIImageView *bg = [[UIImageView alloc] initWithFrame:CGRectMake(0 , 0, 572, 206)];  
    [bg setImage:[UIImage imageNamed:@"bg.jpg"]];  
    [self.view addSubview:bg];  
  
    // Crea el botón  
    [self addButton];  

   // Ahora inicializas el jugador  
    [self initPlayer];  
}  
</pre>
<p>Compila y ejecuta. El personaje apareció en la pantalla verdád?</p>
<div class="imgbox">
    <img src="http://elbleg.com/wp-content/uploads/2010/08/6-20100819-025059.jpg" />
</div>
<h2>Paso 7: Haciendo el personaje saltar</h2>
<p>Ahora la parte divertida. Sobre <code>addButton</code>, agregá:</p>
<pre class="c" name="code">
- (void)cleanStance {  
    [self.player setImage:nil];  
    self.player.animationImages = nil;  
}  
-(void)jumpStance {  
    [self cleanStance];  
  
    NSArray *imageArray = [[NSArray alloc] initWithObjects:  
                                                   [UIImage imageNamed:@"jump1.png"],  
                                                   [UIImage imageNamed:@"jump2.png"], nil];   
  
        self.player.animationImages = imageArray;  
        self.player.animationDuration = 0.3;  
        self.player.contentMode = UIViewContentModeBottomLeft;  
        [self.view addSubview:self.player];  
        [self.player startAnimating];  
}  
</pre>
<p>El primer método que agregaste elimina cualquier imagen asociada al objeto player. Esto te sirve para limpiar cuadros de animación que se hayan usado antes. El segundo método agrega una animación sencilla al objeto player que va a aparece mientras el objeto se mueve.</p>
<p>Después del método jumpStance agregá: </p>
<pre class="c" name="code">
- (void)jump:(UIImageView *)image {  
    [self jumpStance];  
    [UIView beginAnimations:nil context:NULL];  
    [UIView setAnimationDuration: 0.3];  
    [UIView setAnimationCurve: UIViewAnimationCurveEaseOut];  
    [UIView setAnimationBeginsFromCurrentState:YES];  
        image.transform = CGAffineTransformMakeTranslation(0, -40);  
    [UIView commitAnimations];  
}  
</pre>
<p>Este método es el que mueve el jugador. Primero cambia el set de imágenes y luego lo mueve 40 pixels verticalmente.</p>
<p>La linea:</p>
<pre class="c" name="code">
[UIView setAnimationCurve: UIViewAnimationCurveEaseOut];  
</pre>
<p>Agrega un efecto de easing a la animación, así se ve un poco más realista, creo.</p>
<p>Cambiá el método buttonPressed para que quede algo así:  </p>
<pre class="c" name="code">
- (void)buttonPressed {  
    [self jump:self.player];  
}  
</pre>
<p>Compila y ejecuta otra vez. Cuando presionas el botón el personaje debe saltar, pero se va a quedar congelado en el aire al mejor estilo de matrix. Buen progreso no? Ahora dejemos que baje. </p>
<h2>Paso 8: Terminando la animación del personaje</h2>
<p>Antes del método jump agregá:</p>
<pre class="c" name="code">
-(void)fall:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {  
    [self cleanStance];  
    [self normalStance];  
  
    [UIView beginAnimations:nil context:NULL];  
    [UIView setAnimationCurve: UIViewAnimationCurveEaseOut];  
    [UIView setAnimationBeginsFromCurrentState:YES];  
    [UIView setAnimationDuration:0.2];  
        self.player.transform = CGAffineTransformMakeTranslation(0, 0);  
    [UIView commitAnimations];  
}  
</pre>
<p>Esto hará que el personaje regrese a un estado normal y se mueva a su posición inicial.<br />
Ahora, cambiá el método <code>jump</code> para que quede así:</p>
<pre class="c" name="code">
- (void)jump:(UIImageView *)image {  
    [self jumpStance];  
    [UIView beginAnimations:nil context:NULL];  
    [UIView setAnimationDuration: 0.3];  
    [UIView setAnimationCurve: UIViewAnimationCurveEaseOut];  
    [UIView setAnimationBeginsFromCurrentState:YES];  
  
    // Ejecuta fall cuando la animación termine  
    [UIView setAnimationDelegate:self];  
    [UIView setAnimationDidStopSelector:@selector(fall:finished:context:)];  
    image.transform = CGAffineTransformMakeTranslation(0, -40);  
    [UIView commitAnimations];  
}  
</pre>
<p>Compila y ejecuta. Ryu debe saltar de felicidad y regresar al suelo cuando presiones el botón rojo. Es todo.</p>
<h2>Conclusion, Conclusion, Conclusion&#8230;</h2>
<p>Creo que con esto te queda un mejor entendimiento de algunas de las clases más usadas como <code>UIButton, NSLog, UIImageView</code> y cómo ejecutar animaciones. Podés usar un enfoque similar para agregar otros botones a la pantalla para ejecutar diferentes eventos u otras acciones en otros objetos.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/objective-c/evento-touch-y-animacio%cc%81n-para-juegos-ba%cc%81sica-con-objective-c.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Primer reunión del Grupo de tecnologías móviles. Vas?</title>
		<link>http://www.elbleg.com/bleg/primer-reunion-del-grupo-de-tecnologias-moviles-vas.html</link>
		<comments>http://www.elbleg.com/bleg/primer-reunion-del-grupo-de-tecnologias-moviles-vas.html#comments</comments>
		<pubDate>Fri, 11 Jun 2010 22:18:19 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[Blëg]]></category>

		<guid isPermaLink="false">http://www.elbleg.com/?p=302</guid>
		<description><![CDATA[El interés por el desarrollo para dispositivos móviles está creciendo bastante rápido en Costa Rica, buena prueba de ello es la creación del primer grupo de investigación de este tipo de tecnologías conocido en Latinoamérica (que alguien me corrija si me equivoco), iniciativa de un conjunto de profesionales y estudiantes en áreas que van desde [...]]]></description>
			<content:encoded><![CDATA[<p>El interés por el desarrollo para dispositivos móviles está creciendo bastante rápido en Costa Rica, buena prueba de ello es la creación del primer grupo de investigación de este tipo de tecnologías conocido en Latinoamérica (<em>que alguien me corrija si me equivoco</em>), iniciativa de un conjunto de profesionales y estudiantes en áreas que van desde diseño gráfico, propiedad intelectual y desde luego ingeniería en sistemas. </p>
<p>Pues bien, el Grupo de Investigación de Tecnologías Móviles (<a href="http://twitter.com/MovilCR">@MovilCR</a> en twitter) ya echa a andar sus reuniones, la primera de estas será este 16 de Junio a las 7 de la noche en el Auditorio de la Universidad Latina. En esta reunión se pretende explicar un poco el fondo y objetivos del grupo, la forma en que se trabajaría con estudiantes interesados en el área y con profesionales que ya trabajan en ella. Esta primer reunión promete bastante contenido a modo de micro charlas de 5 minutos que mostrarían a grosso modo las temáticas a abarcar en el grupo.</p>
<p>En fin. Si te interesa y estás en Costa Rica para la fecha, sos más que bienvenido. La información completa de la reunión la encontrás en su blog:<br />
<a href="http://gitmocr.org/reunion/1">http://gitmocr.org/reunion/1</a></p>
<p>[UPDATE 17-06-2010]<br />
Las fotos, vídeos y presentaciones que se hicieron ese día están disponibles acá:<br />
<a rel="colleague" href="http://gitmocr.org/reunion/resumen-de-la-primer-reunion">http://gitmocr.org/reunion/resumen-de-la-primer-reunion</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/bleg/primer-reunion-del-grupo-de-tecnologias-moviles-vas.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Bot de Twitter en una línea de código</title>
		<link>http://www.elbleg.com/opensource/bot-de-twitter-en-una-linea-de-codigo.html</link>
		<comments>http://www.elbleg.com/opensource/bot-de-twitter-en-una-linea-de-codigo.html#comments</comments>
		<pubDate>Fri, 01 Jan 2010 01:24:11 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[OpenSource]]></category>
		<category><![CDATA[Utilidades]]></category>
		<category><![CDATA[BASH]]></category>
		<category><![CDATA[bot]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://www.elbleg.com/?p=288</guid>
		<description><![CDATA[
            No, no es broma. Hay quienes hacen ver como si hacer un bot para twitter fuera una gran haza&#241;a. Y en realidad es juego de ni&#241;os. Hace unos meses hice un cliente para twitter en una l&#237;nea&#8230; ahora se me antoj&#243; hacer un [...]]]></description>
			<content:encoded><![CDATA[<p>
            No, no es broma. Hay quienes hacen ver como si hacer un bot para twitter fuera una gran haza&ntilde;a. Y en realidad es juego de ni&ntilde;os. Hace unos meses hice un <a href="http://www.elbleg.com/opensource/cliente-de-twitter-en-una-sola-linea.html">cliente para twitter en una l&iacute;nea</a>&#8230; ahora se me antoj&oacute; hacer un Bot en la misma cantidad de espacio.
        </p>
<p><span id="more-288"></span></p>
<p>
            Esto es posible hacerlo utilizando una &uacute;nica l&iacute;nea de BASH, el <a href="http://apiwiki.twitter.com/Streaming-API-Documentation">API de Streaming de twitter</a> y un poco de vagancia.
        </p>
<p>
            Usando unos cuantos comandos encadenados este bot escucha concurrencias de la palabra &quot;bot&quot; en la twittersfera y sigue la persona que lo escribi&oacute;. Si si&#8230; totalmente in&uacute;til, pero a modo de ejemplo funciona.
        </p>
<p>        <script src="http://gist.github.com/266989.js?file=bot.sh"></script></p>
<p>
            Ac&aacute; hay una versi&oacute;n con algunos espacios extra para legibilidad (el script no funciona con ese espacio):</p>
<p>        <script src="http://gist.github.com/266997.js?file=bot_explicado.sh"></script></p>
<p>
            <em>PD: S&iacute;, ya me d&iacute; cuenta que tiene 400 columnas.</em>
        </p>
<p>
            <em>PD2: No, no deber&iacute;a de usarse en producci&oacute;n, tan solo es un ejemplo de lo sencillo que es hacer un Bot.</em>
        </p>
<p>
            <em>PD3: Y no&#8230; esta vez no voy a hacer conclusi&oacute;n.</em>
        </p>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/opensource/bot-de-twitter-en-una-linea-de-codigo.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>10 buenas razones para usar Firebug</title>
		<link>http://www.elbleg.com/web-dev/10-buenas-razones-para-usar-firebug.html</link>
		<comments>http://www.elbleg.com/web-dev/10-buenas-razones-para-usar-firebug.html#comments</comments>
		<pubDate>Mon, 28 Dec 2009 06:14:11 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[Web Dev]]></category>
		<category><![CDATA[consola]]></category>
		<category><![CDATA[firebug]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[performance testing]]></category>
		<category><![CDATA[xhtml]]></category>
		<category><![CDATA[XMLHttpRequest]]></category>

		<guid isPermaLink="false">http://www.elbleg.com/?p=271</guid>
		<description><![CDATA[
            Firebug una de las herramientas que ha revolucionado la forma en que hacemos web hoy en día, su uso nos es indispensable para muchos y en lo personal es la herramienta que más utilizo para trabajar después de Textmate. 
La idea con este [...]]]></description>
			<content:encoded><![CDATA[<p>
            Firebug una de las herramientas que ha revolucionado la forma en que hacemos web hoy en día, su uso nos es indispensable para muchos y en lo personal es la herramienta que más utilizo para trabajar después de Textmate. </p>
<p>La idea con este post, es recorrer diez de las mejores caracteristicas de Firebug. Así quienes no lo usan lo conocen y quienes lo conocen de repente puedan encontrarse con algo nuevo.
        </p>
<p><span id="more-271"></span></p>
<h2>
            1. Consola<br />
        </h2>
<p>
            La primer cosa que vas a ver cuando abrís firebug va a ser el panel de consola . Después de verlo un momento podrías darte cuenta que es una versión alternativa de la consola de errores de Firefox que básicamente nos sirve para:
        </p>
<ul>
<li>Registro de errores, advertencias y avisos
            </li>
<li>Habilidad para ejecutar código JavaScript
            </li>
</ul>
<p>
            Pero firebug lo extiende un poco más, así que en su consola podés hacer cosas mucho más complejas como:
        </p>
<ul>
<li>Registrar errores de Javascript, CSS, XML, XMLHttpRequest (AJAX) y de Chrome (no el browser&#8230; Si no de funcionalidad interna de firefox)
            </li>
<li>Ejecutar JavaScript en la página web actual
            </li>
<li>Usar el objeto console para hacer output desde tu scripts
            </li>
</ul>
<pre class="js" name="code">
    &lt;html&gt;
    &lt;head&gt;
    &lt;script type="text/javascript"&gt;
        console.time(1);
        console.log('la seccion de scripts comenzo a ejecutarse');
        console.warn('mensaje warning');
        console.error('mensaje error');
        console.info('mensaje info');
        console.log(
        'terminando la ejecucion del script\n',
        'la ejecucion tardo:'
        );
        console.timeEnd(1);
    &lt;/script&gt;
    &lt;/head&gt;
    &lt;/html&gt;
</pre>
<p>
            Fijate en el código arriba, tiene algunos ejemplos de uso del objeto console de firebug, imaginate que abrís que ejecutás ese HTML. Eso te va a mostrar algo como esto en la consola:
        </p>
<p>
            <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/console.png" width="663" height="271" alt="Console" />
        </p>
<h2>
            2. HTML<br />
        </h2>
<p>
            El segundo panel &#8211; y en el que creo que vas a pasar mucho tiempo &#8211; se divide en varias secciónes que vamos a revisar acá.
        </p>
<p>
            <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/html.png" width="664" height="272" alt="Html" />
        </p>
<ol>
<li>Este botón es equivalente al &#8220;Inspect Element&#8221; que aparece en el menú contextual. Aparte de ser muy útil para seleccionar elementos en la página, también destaca el elemento seleccionado con un borde.
            </li>
<li>En esta sección tenemos la jerarquía del elemento que tenemos seleccionado y la habilidad de efectuar una serie de acciones en cada uno de los componentes de la jerarquía como:
<ul class="">
<li>Copiar el inner HTML
                    </li>
<li>Crear expresiones de XPath
                    </li>
<li>Adjuntarle un observador de eventos (y registrarlos en la consola)
                    </li>
<li>Borrar el elemento
                    </li>
<li>Editar el elemento y sus nodos hijos.
                    </li>
<li>Mover el elemento a la pestaña DOM para inspeccionarlo.
                    </li>
</ul>
</li>
<li>Es la ventana principal del panel; util para recorrer todo el html, hacer modificaciónes rápidas al código y encontrar errores (Como cerrar un div muy pronto). El menú contextual tiene las mismas opciones que la sección 2
            </li>
<li>En esta sección se muestran los estilos computados por el browser. La posibilidad de hacer modificaciones en tiempo real al estilo y la habilidad inspeccionar herencias me parecen que son las caracteristicas más importantes.
            </li>
<li>En esta sección podés examinar fácilmente el box model de un elemento: tamaño del contenido, padding, offsets, márgenes y bordes.
            </li>
<li style="list-style: none">
                <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/layout.png" width="655" height="245" alt="Layout" />
            </li>
<li>La sección DOM genera una lista con todos los métodos y propiedades del elemento seleccionado.
            </li>
<li style="list-style: none">
                <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/DOM.png" width="641" height="246" alt="DOM" />
            </li>
</ol>
<h2>
            3. CSS<br />
        </h2>
<p>
            La principal diferencia entre este panel y el que está como sección dentro de la pestaña HTML es que acá podés trabajar con estilos que no han sido interpretados por el browser aún, o sea que no han sido computados. De nuevo voy a destacarte y numerar las secciones (y características esta vez). </p>
<p><img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/css.png" width="700" height="273" alt="Css" />
        </p>
<ol>
<li>Si la página en la que estás trabajando contiene múltiples hojas de estilo podés seleccionar solo la que te interese ver La región principal donde se muestra el código
            </li>
<li>Modifica fácilmente las propiedades del CSS.
            </li>
<li>Podés deshabilitar el CSS desde ahí.
            </li>
</ol>
<h2>
            4. Script<br />
        </h2>
<p>
            A veces, cuando escribís JavaScript tenés que ensuciarte un poco las manos. La mayor parte del tiempo te vas a ver trabajando con la consola; Pero en condiciones extremas vas a tener que pasarte al script panel. Dadas esas condiciones extremas (que ocurren comúnmente), te presento este panel, así te empezás a familiarizar con él.
        </p>
<p>
            <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/script.png" width="699" height="272" alt="Script" />
        </p>
<ol>
<li>Un Dropdown para escoger el script que querés trabajar.
            </li>
<li>Funciones para Debugging: <em>continue, step in, step over y step out</em>. Estas se habilitan solamente cuando el código en ejecución llega a un breakpoint.
            </li>
<li>Sección principal. Acá colocás (y quitás) los breakpoints, también sirve para inspeccionar el código Javascript.
            </li>
<li>Similar al panel DOM panel, la sección Watch muestra los métodos y parametros para el código que se está debuggeando.
            </li>
<li>Muestra el stack de funciones en tiempo real.
            </li>
<li>Lista los breakpoints que se encuentran activos con un link a la línea donde se encuentra. Desde acá solo podés eliminarlos.
            </li>
</ol>
<h2>
            5. DOM<br />
        </h2>
<p>
            Es lo mismo que HTML-&gt;DOM. Dado que nada cambia de lo que te mencioné anteriormente, pasemos a la siguiente sección.
        </p>
<h2>
            6. Net<br />
        </h2>
<p>
            Curioso de cuanto tiempo tarda la página en cargar? O querés saber cual pedido tarda más tiempo en completarse? Afortunadamente, todo eso puede hacerse en el panel Net.
        </p>
<p>
            <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/net.png" width="790" height="270" alt="Net" />
        </p>
<ol>
<li>Los pedidos pueden filtrarse de acuerdo a su tipo.
            </li>
<li>Todo pedido es mostrado en esta sección. Al final de la lista vemos un sumario que contiene: Numero de pedidos, tamaño, cuanto fué guardado en caché y el tiempo total que tomó completarlos.
            </li>
<li>Revela más detalles como: HTTP headers, respuesta y cache.
            </li>
</ol>
<h3>
            Pruebas de desempeño (Performance Testing)<br />
        </h3>
<p>
            Quedés probar el desempeño de una función o un bucle específico? Podés usar el &#8220;timer&#8221; de Firebug.
        </p>
<pre class="js" name="code">
    function medirTiempo(){
        console.time("MiTimer");
        for(x=5000; x &gt; 0; x--){}
        console.timeEnd("MiTimer");
    }
</pre>
<p>
            Tres pasos. Empezá por llamar &#8220;console.time&#8221; y le pasás un único key. Luego de esto ponés el código que necesitás probar. Finalmente, llamás “console.timeEnd”, y de nuevo como único parámetro, le pasás el key que utilizaste anteriormente. Voilá.
        </p>
<h2>
            7. Reference<br />
        </h2>
<p>
            <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/reference.png" width="676" height="270" alt="Reference" />
        </p>
<p>
            Este es un panel adicional, un add-on creado por CodeBurner. Como el nombre lo indica, con este panel tenés acceso rápido a las referencias de HTML y CSS. Me parece que el panel se explica solito.
        </p>
<h2>
            8. PixelPerfect<br />
        </h2>
<p>
            <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/pixelperfect.png" width="672" height="269" alt="Pixelperfect" />
        </p>
<p>
            Si has hecho slicing de un PSD, ya sabés el tiempo que nos quita en cada elemento de la composición. Y es ahí donde PixelPerfect demuestra su poder. Este add-on te ayudará bastante en esa tediosa tarea mostrandote cómo deben ir colocados los elementos con la ayuda de imagenes superpuestas al html.
        </p>
<ol>
<li>Con este botón podés agregar varias imágenes superpuestas para la página actual.
            </li>
<li>Lista de superposiciones, desde acá podés agregar o quitar las imágenes.
            </li>
<li>Configuración de las superposiciones.
            </li>
</ol>
<h2>
            9. YSlow<br />
        </h2>
<p>
            Un buen add-on creado por Yahoo!. Este te sugiere mejoras basado en una serie de test de velocidad que hace. Con YSlow, podés obtener el grado de desempeño de un website. Podés identificar fácilmente los puntos que pueden ser mejorados, además de una serie de recomendaciones para hacerlo.
        </p>
<p>
            <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/yslow1.png" width="661" height="319" alt="Yslow1" />
        </p>
<p>
            Aparte de las estadisticas que te muestra YSlow, te recomiendo JSLint.com para evaluar el JavaScript y Smush.it para las imágenes.
        </p>
<p>
            <img <img src="http://elbleg.com/wp-content/themes/bleg/images/posts/firebug/yslow2.png" width="659" height="453" alt="Yslow2" />
        </p>
<h2>
            10. FirePHP<br />
        </h2>
<p>
            Y por último, pero no menos importante, FirePHP. Con este add-on, podés enviar información (warnings, errors, logging, info) transparentemente a la consola desde tu código PHP. Un ejemplo sería:
        </p>
<pre class="php" name="code">

            &lt;?php
                FB::log('Log message');
                FB::info('Info message');
                FB::warn('Warn message');
                FB::error('Error message');
            ?&gt;
</pre>
<h2>
            Conclusión<br />
        </h2>
<p>
            Y dale con las conclusiones&#8230; Meh&#8230; Bueno ok&#8230; Va.
        </p>
<p>
            La idea con esta pequeña lista de paneles/add-on es que se te haga la vida como developer un poco más fácil &#8212; tal como me lo ha hecho a mi.
 </p>
<p>Al final, los bugs siempre pasan, lo realmente malo es no estar preparado para resolverlos.</p>
<p> Acá la lista de links para los add-ons:
        </p>
<p>
            <a href="https://addons.mozilla.org/ro/firefox/addon/1843" rel="external">Firebug</a>,<br />
            <a href="https://addons.mozilla.org/ro/firefox/addon/10273" rel="external">CodeBurner</a>,<br />
            <a href="https://addons.mozilla.org/ro/firefox/addon/7943" rel="external">PixelPerfect</a>,<br />
            <a href="https://addons.mozilla.org/ro/firefox/addon/5369" rel="external">YSlow</a>,<br />
            <a href="http://www.firephp.org/" rel="external">FirePHP</a>
        </p>
<p>
            Que te sirva.
        </p>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/web-dev/10-buenas-razones-para-usar-firebug.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Titanium en el Tech Camp Costa Rica</title>
		<link>http://www.elbleg.com/bleg/titanium-en-el-tech-camp-costa-rica.html</link>
		<comments>http://www.elbleg.com/bleg/titanium-en-el-tech-camp-costa-rica.html#comments</comments>
		<pubDate>Tue, 17 Nov 2009 19:06:37 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[Blëg]]></category>

		<guid isPermaLink="false">http://www.elbleg.com/?p=259</guid>
		<description><![CDATA[Este lunes tuve el honor de conversar sobre el desarrollo de aplicaciones para dispositivos móviles usando tecnologías web. Fué impresionante la acogida que tuvo el tema y muy refrescante responder tantas preguntas. No tengo palabras para agradecer.

Conversamos un poco sobre la arquitectura de la plataforma en sí. Del aporte en tiempo y know-how que provee [...]]]></description>
			<content:encoded><![CDATA[<p>Este lunes tuve el honor de conversar sobre el desarrollo de aplicaciones para dispositivos móviles usando tecnologías web. Fué impresionante la acogida que tuvo el tema y muy refrescante responder tantas preguntas. No tengo palabras para agradecer.<br />
<span id="more-259"></span><br />
Conversamos un poco sobre la arquitectura de la plataforma en sí. Del aporte en tiempo y know-how que provee y de lo rápido que crece gracias a la comunidad.</p>
<p>Muchas gracias a todos los que asistieron (y no se durmieron). Sí alguno tiene dudas extras o alguna sugerencia para el futuro, soy todo oidos. </p>
<p>También si alguien quiere mostrar esta presentación en su empresa o user group todos los contenidos son abiertos. Titanium tiene una iniciativa llamada App-U que apoya estos meet-ups enviando tshirts, stickers y otras chucherías para los asistentes así que si te interesa solo decime, no importa si no estás en Costa Rica o EEUU.</p>
<p>Acá dejo la presentación y los archivos de ejemplo que vimos.</p>
<div style="width:425px;text-align:left" id="__ss_2521296"><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=titanium-091117121020-phpapp01&#038;rel=0&#038;stripped_title=cero-a-app-en-una-hora" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=titanium-091117121020-phpapp01&#038;rel=0&#038;stripped_title=cero-a-app-en-una-hora" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">presentations</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/whoisyeco">Yëco</a>.</div>
</div>
<p><a href="http://www.elbleg.com/share/code.zip">Codigo de Ejemplo</a>.</p>
<p>También les dejo la <a target="_blank" href="http://twitpic.com/q0nxa">foto de unos amigos.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/bleg/titanium-en-el-tech-camp-costa-rica.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Optimizando JavaScript para un rendimiento extremo y bajo consumo de memoria</title>
		<link>http://www.elbleg.com/web-dev/javascript/optimizando-javascript-para-un-rendimiento-extremo-y-bajo-consumo-de-memoria.html</link>
		<comments>http://www.elbleg.com/web-dev/javascript/optimizando-javascript-para-un-rendimiento-extremo-y-bajo-consumo-de-memoria.html#comments</comments>
		<pubDate>Sun, 15 Nov 2009 08:07:24 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Web Dev]]></category>

		<guid isPermaLink="false">http://www.elbleg.com/?p=244</guid>
		<description><![CDATA[
			En mis muy esporádicos ratos libres estoy haciendo un pequeño juego en JavaScript y he tenido que tomar algunas medidas para agilizar el código. La idea en este post es mostrar algunos trucos que he aprendido en el proceso, algunos no los he visto mencionados en otras partes, así que no está de más compartirlos.
		

			Muchos [...]]]></description>
			<content:encoded><![CDATA[<p>
			En mis muy esporádicos ratos libres estoy haciendo un pequeño juego en JavaScript y he tenido que tomar algunas medidas para agilizar el código. La idea en este post es mostrar algunos trucos que he aprendido en el proceso, algunos no los he visto mencionados en otras partes, así que no está de más compartirlos.
		</p>
<p>
			Muchos de los tips de optimización para JavaScript involucran cosas que se ven más típicamente en otros sitios, como por ejemplo minimizar la cantidad de modificaciones al DOM. Pero en este caso es un poco diferente, ya que era el script por sí mismo era quien debía correr más rápido &#8211; No trabaja con el DOM ni nada, solo procesa muchos datos.
		</p>
<p><span id="more-244"></span></p>
<h2>
			Encontrando la raíz del problema<br />
		</h2>
<p>
			Antes de iniciar cualquier optimización, el código debe ser perfilado para saber qué parte es la que está corriendo despacio. La mejor herramienta para lograr esto, es definitivamente el Profiler de Firebug. Sin este probablemente hubiese tenido muchas más dificultades para encontrar problemas y probar cómo las cosas que cambiaba afectaban la velocidad.
		</p>
<p>
			El Profiler lo encontrás en la consola del Firebug. Solo dale clic en el botón ‘profiler’ una vez para iniciar el <em>perfilamiento (si es que existe la palabra)</em> y clicás de nuevo para detenerlo. Después de detenerlo vas a recibir una lista informativa de las funciones que han sido llamadas y cuanto tiempo tomó cada una en ejecutarse.
		</p>
<h3>
			Problema 1: Iteraciones, cantidad de datos<br />
		</h3>
<p>
			El primer problema que me abofeteó fué la enorme cantidad de datos que se debían de guardar. Un mapa de 128&#215;128 requiere 16,384 iteraciones para ser completamente procesado. A primer vista no parece tanto, pero solamente iterar la data, sin hacer nada más, causaba un golpe mucho mayor del que pasaría en muchos otros lenguajes. Por extraño que pueda parecer, podés usar un do-while invertido para acelerar las iteraciones, o sea en lugar de usar un ciclo con for y contar sumando, usás un ciclo con do-while y contás restando. </p>
<pre class="js" name="code">
			var i = data.length;
			do {
			 /* algo que hacer */
			} while(--i);
</pre>
<p>Por qué es más rápido? Aparentemente el simple hecho de remover la condicion usada para comprobar cuando el loop termine hace gran parte de la diferencia. Hacer -i en vez de i- también ayuda un poco. </p>
<p>El problema con este enfoque es que no siempre es aplicable.</p>
<h3>Problema 2: Llamar funciones</h3>
<p>Fué curioso encontrar que el simple hecho de llamar una función agrega un overhead significativo. Así que llamar una función dentro de uno de esos ciclos grandes en los for puede agregar mucho tiempo de procesamiento.</p>
<p>Como resolverlo? Colocando el código de la función dentro del loop.</p>
<p>Sí, raro. Pero si mueves el código de la función y lo colocas dentro del loop en lugar de llamar la función vas a tener una mejora significativa.  Tiene como gran desventaja que reduce la legibilidad del código, además de que le abre las puertas a la duplicación de código si la función se usa en más de un lugar.</p>
<p>Por raro que sea, esto fué uno de los propulsores más grandes de performance, que en este caso particular, era más importante que un código legible.</p>
<h3>Problema 3: Limitaciones de la memoria</h3>
<p>Dado al bajo monto de memoria disponible en el dispositivo al que va dirigido el juego. La aplicación se quedó sin memoria en varias ocasiones.</p>
<p>Primero, el tamaño del mapa era de 300&#215;300, lo que hacía que el teléfono se quedara sin memoria casi de inmediato. Para esto no hubo más remedio que reducir el tamaño a un 128&#215;128. Usar 300&#215;300 pudo también tener otras repercusiones con el performance, porque la cantidad de data hubiese sido mucho mayor para dibujarlo.</p>
<p>Segundo, cuando implementé la funcionalidad para cargar y salvar el juego, el app de nuevo se quedaba sin memoria. Esto probablemente causado porque el data del mapa era serializado a JSON.</p>
<p>La idea que resolvió esto: Cortar el data en pedazitos pequeños.</p>
<p>Entonces, en lugar de guardar todo el array del mapa de 128&#215;128 de una sola vez, el código lo hace en 8 partes. De este modo el tamaño del JSON serializado se mantiene pequeño y la aplicación no se queda sin memoria.</p>
<p>Lo mismo se hace cuando carga, Como el JSON es guardado en 8 bloques separados, al cargar se meten dentro del array uno por uno.</p>
<h3>Más optimizaciones: Dividir y Flood numbers</h3>
<p>Como parte de la lógica del juego también eran necesario dividir algunos numeros y asegurarme de que los valores eran números enteros.</p>
<p>Típicamente esto requeriría dividir primero y luego aplicar Math.floor. Como mencioné hace un rato. Llamar funciones puede salir caro.</p>
<p>Hay un truco ‘limpio’ para esto. Y limpio entre comillas porque para algunas personas puede ser confuso si no están familiarizadas con la sintáxis, y esto, pues hace el código un poco dificil de leer.</p>
<p>El truco consiste en usar un bit-shift (no conozco el término en español&#8230;):</p>
<pre class="js" name="code">
				var foo = 10;
				//la mayoría de veces, esto es lo mismo que hacer Math.floor(foo / 4)
				var result = foo >> 2;
</pre>
<p>Hacer  <code> >> 2</code> es, como menciona el comentario, practicamente lo mismo que dividir por 4 y despues llamar un <code>Math.floor</code>. Pero en lugar de dos operaciones, tenés solamente una, por lo tanto puede ser un poco más rápido.</p>
<p>Si no entendés de matemática binaria los bitshifts pueden ser un poco enredados. En palabras simples, si hacés  <code>>></code> con 1, es lo mismo que dividir por 2, 2 es dividir entre 4, 3 es dividir entre 8, y 4 es dividir entre 16 y ahí sigue la idea&#8230;</p>
<p>Como es costumbre, <a target="_blank" href="http://en.wikipedia.org/wiki/Bit_shift#Bit_shifts">hay un buen articulo en Wikipedia sobre esto</a>, el cual es un buen recurso si querés leer más información al respecto.</p>
<h3>Más?: Mete el código en funciones anónimas</h3>
<p>Esta es una sugerencia vieja vieja vieja, pero buena buena buena&#8230; Mete el código en funciones anónimas incluso si no son o usan globales.</p>
<p>Por alguna razón que no podría explicar apropiadamente, esto afecta también la velocidad de ejecución de los scripts.</p>
<p>Así que cuando sea que tengas código en JS en un archivo, recuerda envolverla en una función anónima auto ejecutable como esta:</p>
<pre class="js" name="code">
(function(window) {
  /* todo el código va acá!!*/
})(window);
			</pre>
<p>También podés hacer que la función reciba el objeto window como un argumento para una posible pequeña mejora.</p>
<h3>Por último: Reducí el scope</h3>
<p>Esta amarra con la anterior, agregá variables locales dentro de la función anónima para funciones que se usan normalmente, como Math.round or Math.random</p>
<pre class="js" name="code">
(function(window) {
  var round = Math.round;
  var random = Math.random;
  /* todo el código va acá!!*/
})(window);
</pre>
<h3>Conclusión</h3>
<p>Solo porque ya se me hizo costumbre hacer conclusión&#8230;. En fín. La idea detrás de todo esto es mostrar que hay formas de mejorar la velocidad del JavaScript, incluso cuando no tenga nada que ver con el DOM, pero si de igual modo trabajas con el, no está de más agregar unos tips a lo que ya conoces.</p>
<p>Agregando una cosa más a lo anterior. Hay una cosa más que intenté: Probar si había alguna diferencia entre llamar una función objeto vs una función instancia:</p>
<pre class="js" name="code">
				var x = new Foo();
				x.someFunc();
				//or
				bar.someFunc();
</pre>
<p>Yo no ví diferencia alguna, pero si estás usando las clasicas intancias de POO en lugar de funciones estáticas. Puede que te sirva.</p>
<p>Solo recordá que debes perfilar el código siempre antes y después de una optimización. Para ver donde están las partes que realmente necesitan optimizarse y su hubieron mejoras después de algún cambio.</p>
<p>También considerá que muchas optimizaciones pueden hacer que el código sea dificil de mantener. Así que puedes poner en una balanza que tanto necesitas mejorar el performance. Si no es tanto, a veces es mejor no hacerlo.</p>
<p>Espero que te sirva de algo.</p>
<p><a href="http://codeutopia.net/blog/2009/04/30/optimizing-javascript-for-extreme-performance-and-low-memory-consumption/">Fuente</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/web-dev/javascript/optimizando-javascript-para-un-rendimiento-extremo-y-bajo-consumo-de-memoria.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Snippet: Favoritos recientes de Delicious con PHP</title>
		<link>http://www.elbleg.com/web-dev/snippet-favoritos-recientes-de-delicious-con-php.html</link>
		<comments>http://www.elbleg.com/web-dev/snippet-favoritos-recientes-de-delicious-con-php.html#comments</comments>
		<pubDate>Sat, 14 Nov 2009 07:18:26 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[Php]]></category>
		<category><![CDATA[Web Dev]]></category>

		<guid isPermaLink="false">http://www.elbleg.com/?p=254</guid>
		<description><![CDATA[Este snippet descarga y guarda en cache los bookmarks más recientes de una cuenta en específico en RSS desde el API de Delicious, luego los muestra en un UL de HTML.



function get_delicious()
{
	$cache = dirname(__FILE__) . '/caches/delicious';
	if(filemtime($cache) < (time() - 300))
	{
		@mkdir(dirname(__FILE__) . '/caches', 0777);
		$url = 'https://api.del.icio.us/v1/posts/recent?count=10';
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
		curl_setopt($ch, [...]]]></description>
			<content:encoded><![CDATA[<p>Este snippet descarga y guarda en cache los bookmarks más recientes de una cuenta en específico en RSS desde el API de Delicious, luego los muestra en un UL de HTML.</p>
<p><span id="more-254"></span></p>
<pre class="php" name="code">

function get_delicious()
{
	$cache = dirname(__FILE__) . '/caches/delicious';
	if(filemtime($cache) < (time() - 300))
	{
		@mkdir(dirname(__FILE__) . '/caches', 0777);
		$url = 'https://api.del.icio.us/v1/posts/recent?count=10';
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
		curl_setopt($ch, CURLOPT_TIMEOUT, 5);
		curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

		// agregá delicious.com tu usuario y password en esta línea:
		curl_setopt($ch, CURLOPT_USERPWD, 'usuario:password');
		$data = curl_exec($ch);
		curl_close($ch);
		$cachefile = fopen($cache, 'wb');
		fwrite($cachefile, $data);
		fclose($cachefile);
	}
	else
	{
		$data = file_get_contents($cache);
	}
	$xml = simplexml_load_string($data);

	$html = '
<ul>';
	foreach($xml as $item)
	{
		$html .= '
<li><a href="' . $item['href'] . '">' . $item['description'] . '</a> ' . $item['extended'] . '</li>

';
	}
	$html .= '
<li><a href="http://delicious.com/yeco">Mis bookmarks recientes</a></li>

';
	$html .= '</ul>

';
	echo $html;
}

// Mostralos
get_delicious();
</pre>
<p>Este snippet usa <a target="_blank" href="http://us.php.net/manual/en/ref.simplexml.php">SimpleXML</a>, propiedad que fué incluida en PHP5 para hacer la lectura de XML mucho más sencilla.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/web-dev/snippet-favoritos-recientes-de-delicious-con-php.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nombres de Funciones dinámicos con JavaScript</title>
		<link>http://www.elbleg.com/web-dev/javascript/nombres-de-funciones-dinamicos-con-javascript.html</link>
		<comments>http://www.elbleg.com/web-dev/javascript/nombres-de-funciones-dinamicos-con-javascript.html#comments</comments>
		<pubDate>Tue, 27 Oct 2009 06:01:59 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Web Dev]]></category>

		<guid isPermaLink="false">http://www.elbleg.com/?p=236</guid>
		<description><![CDATA[Si te toca hacer aplicaciones un poco avanzadas con JavaScript, vas a toparte con un problema en un punto u otro donde vas a necesitar generar dinámicamente el nombre de una función que quieras llamar. Algo como el equivalente a call_user_func() de PHP.


Algo así es como podés hacerlo:
// Definimos algunas variables
var foo = &#34;Hola&#34;;
var bar [...]]]></description>
			<content:encoded><![CDATA[<p>Si te toca hacer aplicaciones un poco avanzadas con JavaScript, vas a toparte con un problema en un punto u otro donde vas a necesitar generar dinámicamente el nombre de una función que quieras llamar. Algo como el equivalente a <code>call_user_func()</code> de PHP.
</p>
<p><span id="more-236"></span></p>
<p>Algo así es como podés hacerlo:</p>
<pre class="js" name="code">// Definimos algunas variables
var foo = &quot;Hola&quot;;
var bar = &quot;Mundo&quot;;
var nombre_funcion = &quot;decir_&quot; + foo + bar;

/*  Dado que estamos generandolo din&aacute;micamente,
* siempre hay que asegurarse de que la funci&oacute;n
* exista en realidad. */

if (typeof(window[nombre_funcion]) === &quot;function&quot;)
{
	window[nombre_funcion](&quot; Mundo!&quot;);
}
else
{
	throw(&quot;Error.  La funci&oacute;n &quot; + nombre_funcion + &quot; no existe...duh!&quot;);
}

function decir_holaMundo(la_palabra)
{
	alert(&quot;Hola &quot; + la_palabra);
}

// Browser va a alertar un trillad&iacute;simo &quot;Hola Mundo!&quot;</pre>
<p>Cuando lo pensás un rato, tiene mucho sentido considerando que todos los objetos globales en JavasScript son en realidad propiedades del objeto <code>“window”</code>. Fijate en este ejemplo de manzanas y naranjas para entender un poco mejor el concepto.</p>
<pre class="js" name="code">var foo = &quot;manzana&quot;;

function foobar()
{
	var foo = &quot;naranja&quot;;
	alert(window[&quot;foo&quot;]); // alerta &quot;manzana&quot;
	alert(foo); // alert &quot;naranja&quot;
	alert(window[&quot;foobar&quot;]); // alerta la funci&oacute;n foobar
}

foobar();
</pre>
<p>Acá hay otro ejemplo de cuando usar strings para llamar una función puede ser útil. Esta vez llamamos la propiedad de un objeto que hemos creado.</p>
<pre class="js" name="code">function Persona()
{
	this.mensaje = &quot;Hola Mundo!&quot;;
	this.decir_hola = function(a)
	{
		alert(this.mensaje);
	}
}

var Yeco = new Persona();
nombre_funcion = &quot;decir_hola&quot;;
Yeco[nombre_funcion]();</pre>
<p>Ves como es casi lo mismo que el método de arriba usando una función global?</p>
<p>Espero que te sirva en algún momento.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/web-dev/javascript/nombres-de-funciones-dinamicos-con-javascript.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>10 formas de escribir un mejor código en jQuery</title>
		<link>http://www.elbleg.com/web-dev/javascript/10-formas-de-escribir-un-mejor-codigo-en-jquery.html</link>
		<comments>http://www.elbleg.com/web-dev/javascript/10-formas-de-escribir-un-mejor-codigo-en-jquery.html#comments</comments>
		<pubDate>Sun, 23 Aug 2009 07:14:00 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Web Dev]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[chaining]]></category>
		<category><![CDATA[encadenado]]></category>
		<category><![CDATA[jquery data]]></category>
		<category><![CDATA[jquery document ready]]></category>
		<category><![CDATA[optimización]]></category>
		<category><![CDATA[toggleClass]]></category>

		<guid isPermaLink="false">http://www.elbleg.com/?p=227</guid>
		<description><![CDATA[Sin duda alguna, jQuery se ha vuelto la biblioteca de javascript por excelencia, y no lo digo solamente porque me agrade, la gran cantidad de recursos, plugins, tutoriales y documentación, hacen que a muchos les entre la curiosidad y se inicien en javascript aún cuando nunca les atrajo el lenguaje. 
Y bien, ya que la [...]]]></description>
			<content:encoded><![CDATA[<p>Sin duda alguna, jQuery se ha vuelto la biblioteca de javascript por excelencia, y no lo digo solamente porque me agrade, la gran cantidad de recursos, plugins, tutoriales y documentación, hacen que a muchos les entre la curiosidad y se inicien en javascript aún cuando nunca les atrajo el lenguaje. </p>
<p>Y bien, ya que la usamos seguido, o pensamos aprenderla, no nos queda de más conocer unos cuantos tips que nos sirvan para que funcione de un modo más adecuado.<br />
<span id="more-227"></span><br />
Andando por ahí me encontré un post de <a rel="external" href="http://www.myinkblog.com/2009/08/04/10-tips-for-writing-better-jquery-code/">Giulio Bai</a> que aborda este tema en específico y nos dá unas buenas sugerencias al respecto:</p>
<h2>1. $(document).ready (); Siempre</h2>
<p>Todo lo que contenga será ejecutado tan pronto el DOM sea cargado y antes de que los contenidos sean llenados. Te permite agregar eventos a cualquier elemento en la página sin interferir directamente con el markup; todos esos metiches de <code>onload</code>, <code>onclick</code> y <code>onLoQueSea</code> ya no son necesarios, solo escribílos encapsulados ahí.</p>
<p>Un pequeño ejemplo podría ser:</p>
<pre name="code" class="js">$(document).ready(function()
 {
    $(&quot;.dummy&quot;).click(function()
    {
        $(this).css(&#039;color&#039;, &#039;#000000&#039;);
    });
});</pre>
<h2>2. Usá $(window).load ()</h2>
<p>Aunque la vasta mayoría de ejemplos vienen usando el método descrito anteriormente, a veces es mejor evitar poner todo ahí.</p>
<p><code>$(document).ready ()</code> es increíblemente útil, pero ocurre durante el rendering de la página, cuando los objetos aún se están descargando. Por eso las funcionalidades supérfluas como scrollings, arrastrar y soltar, podrían ponerse dentro de una función <code>$(window).load ()</code> ya que esta ejecuta después de que todos los hayan sido descargados y evita que algo se rompa mientras carga la página.</p>
<p>La sintáxis es casi la misma que la de <code>$(document).ready ()</code>:</p>
<pre name="code" class="js">$(window).load (function () {
// métodos de scrolling
});</pre>
<h2>3. Carga sólo lo que realmente necesitas</h2>
<p>Todos han sido tentados a escribir JavaScript que va a ser usado en una sola página de un sitio y luego cargarlo por todas partes, aunque no se use. jQuery se toma el tiempo de revisar todos y cada uno de los elementos que se le dan, y eso pone las cosas un poco lentas.</p>
<p>Hay dos formas que se sugieren para evitar este problema. El más sencillo sería simplemente agregar una clase en el <code>body</code> del html que sea identificador para correr ahí solamente el código necesario.</p>
<pre name="code" class="js">$(document).ready(function()
 {
    if (&#039;body&#039;).hasClass(&#039;home&#039;)
    {
        // home page code
        }
    else if (&#039;body&#039;).hasClass(&#039;blog&#039;)
    {
        // blog code
        }
    // Y as&iacute; sucesivamente
});
</pre>
<p>El otro método, un poco más enredado, sería construir una biblioteca para llamar el código que se necesite desde cada página:</p>
<pre name="code" class="js">var jslib =
{
    home:
    {
        init: function() {
            // home page code
            }
    },

    blog:
    {
        init: function() {
            // blog code
            }
    }

    // Y as&iacute; sucesivamente
}</pre>
<h2>4. Aprende qué es el método &#8216;Data&#8217; y usálo</h2>
<p>Esto es algo muy común, la gente no piensa en ello y siempre escriben cosas como:</p>
<pre name="code" class="js">$('.selector').attr ('alt', 'naranja');</pre>
<p>para guardar y asociar datos misceláneos en el DOM. Esto, es técnicamente incorrecto, además de que es fácil confundirse, sobre todo para las personas que entren al proyecto después.</p>
<p>jQuery ya tiene un método que sirve para guardar datos en el DOM llamado &#8216;data&#8217;. El ejemplo de arriba vendría siendo algo como esto:</p>
<pre name="code" class="js">$('.selector').data ('miColor', 'azul');
// que puede ser pedido con
$('.selector').data ('miColor');</pre>
<p>Este método te permite asociar y guardar datos en cualquier elemento de la página y tener un nombre de referencia.</p>
<h2>5. Usá los selectores personalizados</h2>
<p>Estar familiarizado con los selectores de CSS es util cuando se trata de jQuery. Pero conocer los selectores que trae la biblioteca es de verdad un empujón increíble. Date una vuelta por <a href="http://docs.jquery.com/Selectors">http://docs.jquery.com/Selectors</a> para conocer más de ellos.</p>
<p>Por ejemplo, podrías usar:</p>
<pre name="code" class="js">$("div:contains('hola')").css ('background-color', '#cc0000');</pre>
<p>para pintar de rojo todos los div que contengan la palabra &#8220;hola&#8221; ó</p>
<pre name="code" class="js">$('input:password')</pre>
<p> para obtener todos los campos que sean para password.</p>
<h2>6. Indicadores con clases</h2>
<p>Podés usar indicadores ó flags para monitorear lo que el usuario está haciendo o bien revisar si algo en particular se efectuó o no. El método <code>addClass</code> es bastante útil en este caso ya que provee una forma fácil de agregar una nueva clase css a un elemento. Así que podés chequear la existencia de la clase con la función <code>hasClass</code>.</p>
<p>Un uso muy común de los indicadores se da cuando a aplicación tiene uno o más modos de trabajo; al entrar en el segundo modo, el indicador se fija a un elemento predeterminado y, cuando se necesite, el método <code>hasClass</code> es usado para revisar el modo de trabajo actual. Sencillo no?</p>
<pre name="code" class="js">function editModeOn ()
{
// Inicializa el modo de edición y fija un indicador
$(&#039;#flags&#039;).addClass (&quot;editModeOn&quot;);
// hacer otras cosas
}

function saveData ()
{
// guarda los datos pero primero sale del modo de edición (si está ahí)
if ($(&#039;#flags&#039;).hasClass (&#039;editModeOn&#039;)) {
exitEditMode ();
$(&#039;#flags&#039;).removeClass (&#039;editModeOn&#039;);
}

save ();
}</pre>
<h2>7. No llamés el mismo selector cientos de veces</h2>
<p>De verdad, no lo hagas. Perfectamente en lugar de hacer algo como:</p>
<pre name="code" class="js">$(&#039;p.hola&#039;).css (&#039;color&#039;, &#039;#000000&#039;);
$(&#039;p.hola&#039;).text (&#039;hoola&#039;);
$(&#039;p.hola&#039;).addClass (&#039;parrafo&#039;);
$(&#039;p.hola&#039;).fadeTo (1000, 1);
</pre>
<p>Podés hacer algo como:</p>
<pre name="code" class="js">var $p = $(&#039;p.hola&#039;);
$p.css (&#039;color&#039;, &#039;#000000&#039;);
$p.text (&#039;hola&#039;);
$p.addClass (&#039;parrafo&#039;);
$p.fadeTo (1000, 1);
</pre>
<p>Eso va a mantener la información del selector lista para ser reutilizada.</p>
<h2>8. Encadenando (Casi) todo</h2>
<p>El encadenado, o chaining de jQuery es muy útil.<br />
El código anterior podría ser reescrito como:</p>
<pre name="code" class="js">
$(&#039;p.hola&#039;).css (&#039;color&#039;, &#039;#000000&#039;).text (&#039;hola&#039;).addClass (&#039;parrafo&#039;).fadeTo (1000, 1);</pre>
<p>Eso sí, sin exagerar, es sabido que este patrón puede ser un poco lento.</p>
<h2>9. La utilidad toggleClass</h2>
<p>Podés encender y apagar la clase de un elemento para variar su comportamiento sin mucho esfuerzo. Digamos que tenés una clase <code>.hidden</code> que esconde los elementos que la usen. Fácilmente podrías mostrar los elementos de nuevo usando:</p>
<pre name="code" class="js">
$(&#039;p.hidden&#039;).toggleClass ();
</pre>
<p>Otro punto de <code>toggleClass</code> es que, con el nuevo release de jQuery 1.3.3, el método .toggleClass() va a tener nuevas formas de operar. Va a ser capaz de cambiar multiples clases, además de que podrá quitar y poner todas las clases.</p>
<p>Estás son las formas en que vas a poder usar <code>toggleClass</code>:</p>
<pre name="code" class="js">// Con un elemento dado

	// Cambiar todas las Clases
	$(&#039;div&#039;).toggleClass(); //
	&lt;div&gt;
	$(&#039;div&#039;).toggleClass(); //
	&lt;div class=&quot;a b c&quot;&gt;
	$(&#039;div&#039;).toggleClass( false ); //
	&lt;div&gt;
	$(&#039;div&#039;).toggleClass( true ); //
	&lt;div class=&quot;a b c&quot;&gt;

	// Cambiar m&uacute;ltiples clases
	$(&#039;div&#039;).toggleClass( &quot;a b&quot; ); //
	&lt;div class=&quot;c&quot;&gt;
	$(&#039;div&#039;).toggleClass( &quot;a c&quot; ); //
	&lt;div class=&quot;a&quot;&gt;
	$(&#039;div&#039;).toggleClass( &quot;a b c&quot;, false ); //
	&lt;div&gt;
	$(&#039;div&#039;).toggleClass( &quot;a b c&quot;, true ); //&lt;/div&gt;
	&lt;/div&gt;
	&lt;/div&gt;
	&lt;/div&gt;
	&lt;/div&gt;
	&lt;/div&gt;
	&lt;/div&gt;</pre>
<h2>10. Guardá los resultados de jQuery</h2>
<p>Cuando se trata de funciones, podrías querer tener algunos resultados disponibles en otros lugares. Acá hay dos posibilidades.</p>
<p>Una posible solución sería guardar los resultados dentro de objetos dentro de una variable global, así se pueden usar después:</p>
<pre name="code" class="js">// usamos el objeto Window
	window.$resultados = {
	uno : 0,
	dos : 0
	};

	// esta es la funci&oacute;n que podria corre m&aacute;s de una vez
	function getResults (first, second)
	{
	$resultados.uno = first;
	$resultados.dos = second;
	}

	// corre la funcion
	getResults ($(&#039;li.azul&#039;), $(&#039;a.rojo));
	$resultados.uno.hasClass (&#039;azul&#039;); // true
	$resultados.dos.hasClass (&#039;azul&#039;); // false

	// corre de nuevo
	getResults ($(&#039;li.rojo&#039;), $(&#039;a.azul));
	$resultados.uno.hasClass (&#039;azul&#039;); // false
	$resultados.dos.hasClass (&#039;azul&#039;); // true
</pre>
<p>La otra, y a mi parecer la mejor, como se recomienda en el punto 4 es usar el método Data en lugar de crear una variable global.</p>
<pre name="code" class="js">$.data(window, &quot;resultados&quot;, { uno: false, dos: true });

//Para accesar los valores:

$.data(window, &quot;resultados&quot;).uno; // false
$.data(window, &quot;resultados&quot;).dos; // true

// Y para cambiarlos:

$.data(window, &quot;resultados&quot;).uno = true;
$.data(window, &quot;resultados&quot;).dos = false;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/web-dev/javascript/10-formas-de-escribir-un-mejor-codigo-en-jquery.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Singleton en JavaScript, o: Cómo convertir constructores a JSON</title>
		<link>http://www.elbleg.com/web-dev/javascript/singleton-en-javascript-o-como-convertir-constructores-a-json.html</link>
		<comments>http://www.elbleg.com/web-dev/javascript/singleton-en-javascript-o-como-convertir-constructores-a-json.html#comments</comments>
		<pubDate>Fri, 24 Jul 2009 07:54:13 +0000</pubDate>
		<dc:creator>Yëco</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[singleton]]></category>

		<guid isPermaLink="false">http://www.elbleg.com/?p=219</guid>
		<description><![CDATA[Cuando necesités una sola instancia de una clase de JavaScript, no te molestés escribiendo un constructor, escribí un solo JSON.
El gran poder de los objetos es que los datos y las funciones que hacen algo pueden estar encapsuladas en un mismo objeto. Así que aprovechandonos de ello y para seguir buenas prácticas, a veces metemos [...]]]></description>
			<content:encoded><![CDATA[<p>Cuando necesités una sola instancia de una clase de JavaScript, no te molestés escribiendo un constructor, escribí un solo JSON.</p>
<p>El gran poder de los objetos es que los datos y las funciones que hacen algo pueden estar encapsuladas en un mismo objeto. <span id="more-219"></span>Así que aprovechandonos de ello y para seguir buenas prácticas, a veces metemos todas las utilidades necesarias al &#8220;desnudo&#8221; en el namespace global. Algo así:</p>
<p><code>function getElementsByClassName(cssClassName) {...}</code></p>
<p>Aunque en esto veo dos problemas:</p>
<ul>
<li>Uno pequeño: el nombre de la función es extremadamente largo&#8230; que feo</li>
<li>y uno grande: si estás trabajando con alguna librería, es muy probable que colisione con otra función con un nombre similar y que se comporte diferente</li>
</ul>
<h3>Vamos a arreglarlos</h3>
<p>Podemos crear una clase de utilidades que nos sirva para encapsular esta función (y otras) más o menos así:</p>
<pre name="code" class="js">function DomUtilityBag() {
this.getByClass= function(cssClassName) {...}
}</pre>
<p>e instanciarla:</p>
<pre name="code" class="js">var domUtils = new DomUtilityBag();</pre>
<p>Si has usado constructores, parece obvio y familar no?. Pero los constructores fueron hechos para permitir instanciar cualquier número de objetos del mismo prototype. Por qué necesitaríamos hacer eso con un conjunto de utilidades misceláneas? Usualmente no hay razón, porque no hay datos que se diferencien de una instancia a otra.</p>
<p>Acá entra Singleton y es donde JSON se vuelve muy útil. Con él podemos declarar una única instancia y todos sus miembros de una sola llamada, sin meternos con los constructores:</p>
<pre name="code" class="js">var domUtils = {
getByClass: function(cssClassName) {...}
}</pre>
<h3>haciendolo aún mejor</h3>
<p>Mientras estamos haciendo el <code>domUtils</code> asumamos que esa librería de utilidades podría crecer bastante (siempre lo hacen). Así que vamos a seguir la técnica de YUI para el namespacing, categorizando más las utilidades, y como solo necesitamos una copia, utilizamos JSON para hacerlo. Acá está el esqueleto de mi librería, y le vamos a poner&#8230; eeehh, hmm&#8230; ZAQ, sí ZAQ:</p>
<pre name="code" class="js">var ZAQ = {}  //esto crea un objeto namespace vac&iacute;o

ZAQ.util = {} //un sub-objeto para el paquete de utilidades

//lo granulamos m&aacute;s, con utilidades espec&iacute;ficas para el DOM
ZAQ.util.dom = {
getByClass: function(cssClassName) {...},
elemHasClass: function(elem, className) {...}
}

//podemos agregar m&aacute;s tipos de utilidades en sus propias &quot;categorias&quot;
ZAQ.util.array = {
contains: function(theArray, match) {...}
}
ZAQ.util.string = {
startsWith: function(theString, match) {...},
endsWith:   function(theString, match) {...}
}</pre>
<p>Y así sucesivamente.</p>
<h3>Conclusión?</h3>
<p>Necesitamos una?</p>
<p>Ok, ok&#8230; El fín es que podés usar el poderoso patrón singleton en JavaScript, funciona perfecto para este tipo de librerías de utilidades y un sin fín de cosas más en las que solo necesités una copia corriendo. Mantiene el código fácil de leer, mantiene el namespace intacto y ordenado y además previene colisiones con otras funciones cuando estás integrando otras librerías.</p>
<p>Que te sirva de algo.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.elbleg.com/web-dev/javascript/singleton-en-javascript-o-como-convertir-constructores-a-json.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
